]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_apfloat/tests/ppc.rs
New upstream version 1.55.0+dfsg1
[rustc.git] / compiler / rustc_apfloat / tests / ppc.rs
CommitLineData
3b2f2976 1use rustc_apfloat::ppc::DoubleDouble;
dfeec247 2use rustc_apfloat::{Category, Float, Round};
3b2f2976
XL
3
4use std::cmp::Ordering;
5
6#[test]
7fn ppc_double_double() {
8 let test = DoubleDouble::ZERO;
9 let expected = "0x0p+0".parse::<DoubleDouble>().unwrap();
10 assert!(test.is_zero());
11 assert!(!test.is_negative());
12 assert!(test.bitwise_eq(expected));
13 assert_eq!(0, test.to_bits());
14
15 let test = -DoubleDouble::ZERO;
16 let expected = "-0x0p+0".parse::<DoubleDouble>().unwrap();
17 assert!(test.is_zero());
18 assert!(test.is_negative());
19 assert!(test.bitwise_eq(expected));
20 assert_eq!(0x8000000000000000, test.to_bits());
21
22 let test = "1.0".parse::<DoubleDouble>().unwrap();
23 assert_eq!(0x3ff0000000000000, test.to_bits());
24
25 // LDBL_MAX
dfeec247 26 let test = "1.79769313486231580793728971405301e+308".parse::<DoubleDouble>().unwrap();
3b2f2976
XL
27 assert_eq!(0x7c8ffffffffffffe_7fefffffffffffff, test.to_bits());
28
29 // LDBL_MIN
dfeec247 30 let test = "2.00416836000897277799610805135016e-292".parse::<DoubleDouble>().unwrap();
3b2f2976
XL
31 assert_eq!(0x0000000000000000_0360000000000000, test.to_bits());
32}
33
34#[test]
35fn ppc_double_double_add_special() {
36 let data = [
37 // (1 + 0) + (-1 + 0) = Category::Zero
dfeec247 38 (0x3ff0000000000000, 0xbff0000000000000, Category::Zero, Round::NearestTiesToEven),
3b2f2976
XL
39 // LDBL_MAX + (1.1 >> (1023 - 106) + 0)) = Category::Infinity
40 (
41 0x7c8ffffffffffffe_7fefffffffffffff,
42 0x7948000000000000,
43 Category::Infinity,
44 Round::NearestTiesToEven,
45 ),
46 // FIXME: change the 4th 0x75effffffffffffe to 0x75efffffffffffff when
47 // DoubleDouble's fallback is gone.
48 // LDBL_MAX + (1.011111... >> (1023 - 106) + (1.1111111...0 >> (1023 -
49 // 160))) = Category::Normal
50 (
51 0x7c8ffffffffffffe_7fefffffffffffff,
52 0x75effffffffffffe_7947ffffffffffff,
53 Category::Normal,
54 Round::NearestTiesToEven,
55 ),
56 // LDBL_MAX + (1.1 >> (1023 - 106) + 0)) = Category::Infinity
57 (
58 0x7c8ffffffffffffe_7fefffffffffffff,
59 0x7c8ffffffffffffe_7fefffffffffffff,
60 Category::Infinity,
61 Round::NearestTiesToEven,
62 ),
63 // NaN + (1 + 0) = Category::NaN
dfeec247 64 (0x7ff8000000000000, 0x3ff0000000000000, Category::NaN, Round::NearestTiesToEven),
3b2f2976
XL
65 ];
66
136023e0 67 for (op1, op2, expected, round) in data {
3b2f2976
XL
68 {
69 let mut a1 = DoubleDouble::from_bits(op1);
70 let a2 = DoubleDouble::from_bits(op2);
71 a1 = a1.add_r(a2, round).value;
72
73 assert_eq!(expected, a1.category(), "{:#x} + {:#x}", op1, op2);
74 }
75 {
76 let a1 = DoubleDouble::from_bits(op1);
77 let mut a2 = DoubleDouble::from_bits(op2);
78 a2 = a2.add_r(a1, round).value;
79
80 assert_eq!(expected, a2.category(), "{:#x} + {:#x}", op2, op1);
81 }
82 }
83}
84
85#[test]
86fn ppc_double_double_add() {
87 let data = [
88 // (1 + 0) + (1e-105 + 0) = (1 + 1e-105)
89 (
90 0x3ff0000000000000,
91 0x3960000000000000,
92 0x3960000000000000_3ff0000000000000,
93 Round::NearestTiesToEven,
94 ),
95 // (1 + 0) + (1e-106 + 0) = (1 + 1e-106)
96 (
97 0x3ff0000000000000,
98 0x3950000000000000,
99 0x3950000000000000_3ff0000000000000,
100 Round::NearestTiesToEven,
101 ),
102 // (1 + 1e-106) + (1e-106 + 0) = (1 + 1e-105)
103 (
104 0x3950000000000000_3ff0000000000000,
105 0x3950000000000000,
106 0x3960000000000000_3ff0000000000000,
107 Round::NearestTiesToEven,
108 ),
109 // (1 + 0) + (epsilon + 0) = (1 + epsilon)
110 (
111 0x3ff0000000000000,
112 0x0000000000000001,
113 0x0000000000000001_3ff0000000000000,
114 Round::NearestTiesToEven,
115 ),
116 // FIXME: change 0xf950000000000000 to 0xf940000000000000, when
117 // DoubleDouble's fallback is gone.
118 // (DBL_MAX - 1 << (1023 - 105)) + (1 << (1023 - 53) + 0) = DBL_MAX +
119 // 1.11111... << (1023 - 52)
120 (
121 0xf950000000000000_7fefffffffffffff,
122 0x7c90000000000000,
123 0x7c8ffffffffffffe_7fefffffffffffff,
124 Round::NearestTiesToEven,
125 ),
126 // FIXME: change 0xf950000000000000 to 0xf940000000000000, when
127 // DoubleDouble's fallback is gone.
128 // (1 << (1023 - 53) + 0) + (DBL_MAX - 1 << (1023 - 105)) = DBL_MAX +
129 // 1.11111... << (1023 - 52)
130 (
131 0x7c90000000000000,
132 0xf950000000000000_7fefffffffffffff,
133 0x7c8ffffffffffffe_7fefffffffffffff,
134 Round::NearestTiesToEven,
135 ),
136 ];
137
136023e0 138 for (op1, op2, expected, round) in data {
3b2f2976
XL
139 {
140 let mut a1 = DoubleDouble::from_bits(op1);
141 let a2 = DoubleDouble::from_bits(op2);
142 a1 = a1.add_r(a2, round).value;
143
144 assert_eq!(expected, a1.to_bits(), "{:#x} + {:#x}", op1, op2);
145 }
146 {
147 let a1 = DoubleDouble::from_bits(op1);
148 let mut a2 = DoubleDouble::from_bits(op2);
149 a2 = a2.add_r(a1, round).value;
150
151 assert_eq!(expected, a2.to_bits(), "{:#x} + {:#x}", op2, op1);
152 }
153 }
154}
155
156#[test]
157fn ppc_double_double_subtract() {
158 let data = [
159 // (1 + 0) - (-1e-105 + 0) = (1 + 1e-105)
160 (
161 0x3ff0000000000000,
162 0xb960000000000000,
163 0x3960000000000000_3ff0000000000000,
164 Round::NearestTiesToEven,
165 ),
166 // (1 + 0) - (-1e-106 + 0) = (1 + 1e-106)
167 (
168 0x3ff0000000000000,
169 0xb950000000000000,
170 0x3950000000000000_3ff0000000000000,
171 Round::NearestTiesToEven,
172 ),
173 ];
174
136023e0 175 for (op1, op2, expected, round) in data {
3b2f2976
XL
176 let mut a1 = DoubleDouble::from_bits(op1);
177 let a2 = DoubleDouble::from_bits(op2);
178 a1 = a1.sub_r(a2, round).value;
179
180 assert_eq!(expected, a1.to_bits(), "{:#x} - {:#x}", op1, op2);
181 }
182}
183
184#[test]
185fn ppc_double_double_multiply_special() {
186 let data = [
187 // Category::NaN * Category::NaN = Category::NaN
dfeec247 188 (0x7ff8000000000000, 0x7ff8000000000000, Category::NaN, Round::NearestTiesToEven),
3b2f2976 189 // Category::NaN * Category::Zero = Category::NaN
dfeec247 190 (0x7ff8000000000000, 0, Category::NaN, Round::NearestTiesToEven),
3b2f2976 191 // Category::NaN * Category::Infinity = Category::NaN
dfeec247 192 (0x7ff8000000000000, 0x7ff0000000000000, Category::NaN, Round::NearestTiesToEven),
3b2f2976 193 // Category::NaN * Category::Normal = Category::NaN
dfeec247 194 (0x7ff8000000000000, 0x3ff0000000000000, Category::NaN, Round::NearestTiesToEven),
3b2f2976 195 // Category::Infinity * Category::Infinity = Category::Infinity
dfeec247 196 (0x7ff0000000000000, 0x7ff0000000000000, Category::Infinity, Round::NearestTiesToEven),
3b2f2976 197 // Category::Infinity * Category::Zero = Category::NaN
dfeec247 198 (0x7ff0000000000000, 0, Category::NaN, Round::NearestTiesToEven),
3b2f2976 199 // Category::Infinity * Category::Normal = Category::Infinity
dfeec247 200 (0x7ff0000000000000, 0x3ff0000000000000, Category::Infinity, Round::NearestTiesToEven),
3b2f2976
XL
201 // Category::Zero * Category::Zero = Category::Zero
202 (0, 0, Category::Zero, Round::NearestTiesToEven),
203 // Category::Zero * Category::Normal = Category::Zero
dfeec247 204 (0, 0x3ff0000000000000, Category::Zero, Round::NearestTiesToEven),
3b2f2976
XL
205 ];
206
136023e0 207 for (op1, op2, expected, round) in data {
3b2f2976
XL
208 {
209 let mut a1 = DoubleDouble::from_bits(op1);
210 let a2 = DoubleDouble::from_bits(op2);
211 a1 = a1.mul_r(a2, round).value;
212
213 assert_eq!(expected, a1.category(), "{:#x} * {:#x}", op1, op2);
214 }
215 {
216 let a1 = DoubleDouble::from_bits(op1);
217 let mut a2 = DoubleDouble::from_bits(op2);
218 a2 = a2.mul_r(a1, round).value;
219
220 assert_eq!(expected, a2.category(), "{:#x} * {:#x}", op2, op1);
221 }
222 }
223}
224
225#[test]
226fn ppc_double_double_multiply() {
227 let data = [
228 // 1/3 * 3 = 1.0
229 (
230 0x3c75555555555556_3fd5555555555555,
231 0x4008000000000000,
232 0x3ff0000000000000,
233 Round::NearestTiesToEven,
234 ),
235 // (1 + epsilon) * (1 + 0) = Category::Zero
236 (
237 0x0000000000000001_3ff0000000000000,
238 0x3ff0000000000000,
239 0x0000000000000001_3ff0000000000000,
240 Round::NearestTiesToEven,
241 ),
242 // (1 + epsilon) * (1 + epsilon) = 1 + 2 * epsilon
243 (
244 0x0000000000000001_3ff0000000000000,
245 0x0000000000000001_3ff0000000000000,
246 0x0000000000000002_3ff0000000000000,
247 Round::NearestTiesToEven,
248 ),
249 // -(1 + epsilon) * (1 + epsilon) = -1
250 (
251 0x0000000000000001_bff0000000000000,
252 0x0000000000000001_3ff0000000000000,
253 0xbff0000000000000,
254 Round::NearestTiesToEven,
255 ),
256 // (0.5 + 0) * (1 + 2 * epsilon) = 0.5 + epsilon
257 (
258 0x3fe0000000000000,
259 0x0000000000000002_3ff0000000000000,
260 0x0000000000000001_3fe0000000000000,
261 Round::NearestTiesToEven,
262 ),
263 // (0.5 + 0) * (1 + epsilon) = 0.5
264 (
265 0x3fe0000000000000,
266 0x0000000000000001_3ff0000000000000,
267 0x3fe0000000000000,
268 Round::NearestTiesToEven,
269 ),
270 // __LDBL_MAX__ * (1 + 1 << 106) = inf
271 (
272 0x7c8ffffffffffffe_7fefffffffffffff,
273 0x3950000000000000_3ff0000000000000,
274 0x7ff0000000000000,
275 Round::NearestTiesToEven,
276 ),
277 // __LDBL_MAX__ * (1 + 1 << 107) > __LDBL_MAX__, but not inf, yes =_=|||
278 (
279 0x7c8ffffffffffffe_7fefffffffffffff,
280 0x3940000000000000_3ff0000000000000,
281 0x7c8fffffffffffff_7fefffffffffffff,
282 Round::NearestTiesToEven,
283 ),
284 // __LDBL_MAX__ * (1 + 1 << 108) = __LDBL_MAX__
285 (
286 0x7c8ffffffffffffe_7fefffffffffffff,
287 0x3930000000000000_3ff0000000000000,
288 0x7c8ffffffffffffe_7fefffffffffffff,
289 Round::NearestTiesToEven,
290 ),
291 ];
292
136023e0 293 for (op1, op2, expected, round) in data {
3b2f2976
XL
294 {
295 let mut a1 = DoubleDouble::from_bits(op1);
296 let a2 = DoubleDouble::from_bits(op2);
297 a1 = a1.mul_r(a2, round).value;
298
299 assert_eq!(expected, a1.to_bits(), "{:#x} * {:#x}", op1, op2);
300 }
301 {
302 let a1 = DoubleDouble::from_bits(op1);
303 let mut a2 = DoubleDouble::from_bits(op2);
304 a2 = a2.mul_r(a1, round).value;
305
306 assert_eq!(expected, a2.to_bits(), "{:#x} * {:#x}", op2, op1);
307 }
308 }
309}
310
311#[test]
312fn ppc_double_double_divide() {
313 // FIXME: Only a sanity check for now. Add more edge cases when the
314 // double-double algorithm is implemented.
315 let data = [
316 // 1 / 3 = 1/3
317 (
318 0x3ff0000000000000,
319 0x4008000000000000,
320 0x3c75555555555556_3fd5555555555555,
321 Round::NearestTiesToEven,
322 ),
323 ];
324
136023e0 325 for (op1, op2, expected, round) in data {
3b2f2976
XL
326 let mut a1 = DoubleDouble::from_bits(op1);
327 let a2 = DoubleDouble::from_bits(op2);
328 a1 = a1.div_r(a2, round).value;
329
330 assert_eq!(expected, a1.to_bits(), "{:#x} / {:#x}", op1, op2);
331 }
332}
333
334#[test]
335fn ppc_double_double_remainder() {
336 let data = [
337 // ieee_rem(3.0 + 3.0 << 53, 1.25 + 1.25 << 53) = (0.5 + 0.5 << 53)
338 (
339 0x3cb8000000000000_4008000000000000,
340 0x3ca4000000000000_3ff4000000000000,
341 0x3c90000000000000_3fe0000000000000,
342 ),
343 // ieee_rem(3.0 + 3.0 << 53, 1.75 + 1.75 << 53) = (-0.5 - 0.5 << 53)
344 (
345 0x3cb8000000000000_4008000000000000,
346 0x3cac000000000000_3ffc000000000000,
347 0xbc90000000000000_bfe0000000000000,
348 ),
349 ];
350
136023e0 351 for (op1, op2, expected) in data {
3b2f2976
XL
352 let a1 = DoubleDouble::from_bits(op1);
353 let a2 = DoubleDouble::from_bits(op2);
354 let result = a1.ieee_rem(a2).value;
355
dfeec247 356 assert_eq!(expected, result.to_bits(), "ieee_rem({:#x}, {:#x})", op1, op2);
3b2f2976
XL
357 }
358}
359
360#[test]
361fn ppc_double_double_mod() {
362 let data = [
363 // mod(3.0 + 3.0 << 53, 1.25 + 1.25 << 53) = (0.5 + 0.5 << 53)
364 (
365 0x3cb8000000000000_4008000000000000,
366 0x3ca4000000000000_3ff4000000000000,
367 0x3c90000000000000_3fe0000000000000,
368 ),
369 // mod(3.0 + 3.0 << 53, 1.75 + 1.75 << 53) = (1.25 + 1.25 << 53)
370 // 0xbc98000000000000 doesn't seem right, but it's what we currently have.
371 // FIXME: investigate
372 (
373 0x3cb8000000000000_4008000000000000,
374 0x3cac000000000000_3ffc000000000000,
375 0xbc98000000000000_3ff4000000000001,
376 ),
377 ];
378
136023e0 379 for (op1, op2, expected) in data {
3b2f2976
XL
380 let a1 = DoubleDouble::from_bits(op1);
381 let a2 = DoubleDouble::from_bits(op2);
382 let r = (a1 % a2).value;
383
384 assert_eq!(expected, r.to_bits(), "fmod({:#x}, {:#x})", op1, op2);
385 }
386}
387
388#[test]
389fn ppc_double_double_fma() {
390 // Sanity check for now.
391 let mut a = "2".parse::<DoubleDouble>().unwrap();
dfeec247
XL
392 a = a.mul_add("3".parse::<DoubleDouble>().unwrap(), "4".parse::<DoubleDouble>().unwrap()).value;
393 assert_eq!(Some(Ordering::Equal), "10".parse::<DoubleDouble>().unwrap().partial_cmp(&a));
3b2f2976
XL
394}
395
396#[test]
397fn ppc_double_double_round_to_integral() {
398 {
399 let a = "1.5".parse::<DoubleDouble>().unwrap();
400 let a = a.round_to_integral(Round::NearestTiesToEven).value;
dfeec247 401 assert_eq!(Some(Ordering::Equal), "2".parse::<DoubleDouble>().unwrap().partial_cmp(&a));
3b2f2976
XL
402 }
403 {
404 let a = "2.5".parse::<DoubleDouble>().unwrap();
405 let a = a.round_to_integral(Round::NearestTiesToEven).value;
dfeec247 406 assert_eq!(Some(Ordering::Equal), "2".parse::<DoubleDouble>().unwrap().partial_cmp(&a));
3b2f2976
XL
407 }
408}
409
410#[test]
411fn ppc_double_double_compare() {
412 let data = [
413 // (1 + 0) = (1 + 0)
dfeec247 414 (0x3ff0000000000000, 0x3ff0000000000000, Some(Ordering::Equal)),
3b2f2976
XL
415 // (1 + 0) < (1.00...1 + 0)
416 (0x3ff0000000000000, 0x3ff0000000000001, Some(Ordering::Less)),
417 // (1.00...1 + 0) > (1 + 0)
dfeec247 418 (0x3ff0000000000001, 0x3ff0000000000000, Some(Ordering::Greater)),
3b2f2976 419 // (1 + 0) < (1 + epsilon)
dfeec247 420 (0x3ff0000000000000, 0x0000000000000001_3ff0000000000001, Some(Ordering::Less)),
3b2f2976
XL
421 // NaN != NaN
422 (0x7ff8000000000000, 0x7ff8000000000000, None),
423 // (1 + 0) != NaN
424 (0x3ff0000000000000, 0x7ff8000000000000, None),
425 // Inf = Inf
dfeec247 426 (0x7ff0000000000000, 0x7ff0000000000000, Some(Ordering::Equal)),
3b2f2976
XL
427 ];
428
136023e0 429 for (op1, op2, expected) in data {
3b2f2976
XL
430 let a1 = DoubleDouble::from_bits(op1);
431 let a2 = DoubleDouble::from_bits(op2);
dfeec247 432 assert_eq!(expected, a1.partial_cmp(&a2), "compare({:#x}, {:#x})", op1, op2,);
3b2f2976
XL
433 }
434}
435
436#[test]
437fn ppc_double_double_bitwise_eq() {
438 let data = [
439 // (1 + 0) = (1 + 0)
440 (0x3ff0000000000000, 0x3ff0000000000000, true),
441 // (1 + 0) != (1.00...1 + 0)
442 (0x3ff0000000000000, 0x3ff0000000000001, false),
443 // NaN = NaN
444 (0x7ff8000000000000, 0x7ff8000000000000, true),
445 // NaN != NaN with a different bit pattern
dfeec247 446 (0x7ff8000000000000, 0x3ff0000000000000_7ff8000000000000, false),
3b2f2976
XL
447 // Inf = Inf
448 (0x7ff0000000000000, 0x7ff0000000000000, true),
449 ];
450
136023e0 451 for (op1, op2, expected) in data {
3b2f2976
XL
452 let a1 = DoubleDouble::from_bits(op1);
453 let a2 = DoubleDouble::from_bits(op2);
454 assert_eq!(expected, a1.bitwise_eq(a2), "{:#x} = {:#x}", op1, op2);
455 }
456}
457
458#[test]
459fn ppc_double_double_change_sign() {
460 let float = DoubleDouble::from_bits(0xbcb0000000000000_400f000000000000);
461 {
462 let actual = float.copy_sign("1".parse::<DoubleDouble>().unwrap());
463 assert_eq!(0xbcb0000000000000_400f000000000000, actual.to_bits());
464 }
465 {
466 let actual = float.copy_sign("-1".parse::<DoubleDouble>().unwrap());
467 assert_eq!(0x3cb0000000000000_c00f000000000000, actual.to_bits());
468 }
469}
470
471#[test]
472fn ppc_double_double_factories() {
473 assert_eq!(0, DoubleDouble::ZERO.to_bits());
dfeec247 474 assert_eq!(0x7c8ffffffffffffe_7fefffffffffffff, DoubleDouble::largest().to_bits());
3b2f2976 475 assert_eq!(0x0000000000000001, DoubleDouble::SMALLEST.to_bits());
dfeec247
XL
476 assert_eq!(0x0360000000000000, DoubleDouble::smallest_normalized().to_bits());
477 assert_eq!(0x0000000000000000_8000000000000000, (-DoubleDouble::ZERO).to_bits());
478 assert_eq!(0xfc8ffffffffffffe_ffefffffffffffff, (-DoubleDouble::largest()).to_bits());
479 assert_eq!(0x0000000000000000_8000000000000001, (-DoubleDouble::SMALLEST).to_bits());
3b2f2976
XL
480 assert_eq!(
481 0x0000000000000000_8360000000000000,
482 (-DoubleDouble::smallest_normalized()).to_bits()
483 );
484 assert!(DoubleDouble::SMALLEST.is_smallest());
485 assert!(DoubleDouble::largest().is_largest());
486}
487
488#[test]
489fn ppc_double_double_is_denormal() {
490 assert!(DoubleDouble::SMALLEST.is_denormal());
491 assert!(!DoubleDouble::largest().is_denormal());
492 assert!(!DoubleDouble::smallest_normalized().is_denormal());
493 {
494 // (4 + 3) is not normalized
495 let data = 0x4008000000000000_4010000000000000;
496 assert!(DoubleDouble::from_bits(data).is_denormal());
497 }
498}
499
500#[test]
501fn ppc_double_double_exact_inverse() {
502 assert!(
503 "2.0"
504 .parse::<DoubleDouble>()
505 .unwrap()
506 .get_exact_inverse()
507 .unwrap()
508 .bitwise_eq("0.5".parse::<DoubleDouble>().unwrap())
509 );
510}
511
512#[test]
513fn ppc_double_double_scalbn() {
514 // 3.0 + 3.0 << 53
515 let input = 0x3cb8000000000000_4008000000000000;
516 let result = DoubleDouble::from_bits(input).scalbn(1);
517 // 6.0 + 6.0 << 53
518 assert_eq!(0x3cc8000000000000_4018000000000000, result.to_bits());
519}
520
521#[test]
522fn ppc_double_double_frexp() {
523 // 3.0 + 3.0 << 53
524 let input = 0x3cb8000000000000_4008000000000000;
525 let mut exp = 0;
526 // 0.75 + 0.75 << 53
527 let result = DoubleDouble::from_bits(input).frexp(&mut exp);
528 assert_eq!(2, exp);
529 assert_eq!(0x3c98000000000000_3fe8000000000000, result.to_bits());
530}