github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/cmd/compile/test/testdata/fp_test.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Tests floating point arithmetic expressions 6 7 package main 8 9 import ( 10 "fmt" 11 "testing" 12 ) 13 14 // manysub_ssa is designed to tickle bugs that depend on register 15 // pressure or unfriendly operand ordering in registers (and at 16 // least once it succeeded in this). 17 // 18 //go:noinline 19 func manysub_ssa(a, b, c, d float64) (aa, ab, ac, ad, ba, bb, bc, bd, ca, cb, cc, cd, da, db, dc, dd float64) { 20 aa = a + 11.0 - a 21 ab = a - b 22 ac = a - c 23 ad = a - d 24 ba = b - a 25 bb = b + 22.0 - b 26 bc = b - c 27 bd = b - d 28 ca = c - a 29 cb = c - b 30 cc = c + 33.0 - c 31 cd = c - d 32 da = d - a 33 db = d - b 34 dc = d - c 35 dd = d + 44.0 - d 36 return 37 } 38 39 // fpspill_ssa attempts to trigger a bug where phis with floating point values 40 // were stored in non-fp registers causing an error in doasm. 41 // 42 //go:noinline 43 func fpspill_ssa(a int) float64 { 44 45 ret := -1.0 46 switch a { 47 case 0: 48 ret = 1.0 49 case 1: 50 ret = 1.1 51 case 2: 52 ret = 1.2 53 case 3: 54 ret = 1.3 55 case 4: 56 ret = 1.4 57 case 5: 58 ret = 1.5 59 case 6: 60 ret = 1.6 61 case 7: 62 ret = 1.7 63 case 8: 64 ret = 1.8 65 case 9: 66 ret = 1.9 67 case 10: 68 ret = 1.10 69 case 11: 70 ret = 1.11 71 case 12: 72 ret = 1.12 73 case 13: 74 ret = 1.13 75 case 14: 76 ret = 1.14 77 case 15: 78 ret = 1.15 79 case 16: 80 ret = 1.16 81 } 82 return ret 83 } 84 85 //go:noinline 86 func add64_ssa(a, b float64) float64 { 87 return a + b 88 } 89 90 //go:noinline 91 func mul64_ssa(a, b float64) float64 { 92 return a * b 93 } 94 95 //go:noinline 96 func sub64_ssa(a, b float64) float64 { 97 return a - b 98 } 99 100 //go:noinline 101 func div64_ssa(a, b float64) float64 { 102 return a / b 103 } 104 105 //go:noinline 106 func neg64_ssa(a, b float64) float64 { 107 return -a + -1*b 108 } 109 110 //go:noinline 111 func add32_ssa(a, b float32) float32 { 112 return a + b 113 } 114 115 //go:noinline 116 func mul32_ssa(a, b float32) float32 { 117 return a * b 118 } 119 120 //go:noinline 121 func sub32_ssa(a, b float32) float32 { 122 return a - b 123 } 124 125 //go:noinline 126 func div32_ssa(a, b float32) float32 { 127 return a / b 128 } 129 130 //go:noinline 131 func neg32_ssa(a, b float32) float32 { 132 return -a + -1*b 133 } 134 135 //go:noinline 136 func conv2Float64_ssa(a int8, b uint8, c int16, d uint16, 137 e int32, f uint32, g int64, h uint64, i float32) (aa, bb, cc, dd, ee, ff, gg, hh, ii float64) { 138 aa = float64(a) 139 bb = float64(b) 140 cc = float64(c) 141 hh = float64(h) 142 dd = float64(d) 143 ee = float64(e) 144 ff = float64(f) 145 gg = float64(g) 146 ii = float64(i) 147 return 148 } 149 150 //go:noinline 151 func conv2Float32_ssa(a int8, b uint8, c int16, d uint16, 152 e int32, f uint32, g int64, h uint64, i float64) (aa, bb, cc, dd, ee, ff, gg, hh, ii float32) { 153 aa = float32(a) 154 bb = float32(b) 155 cc = float32(c) 156 dd = float32(d) 157 ee = float32(e) 158 ff = float32(f) 159 gg = float32(g) 160 hh = float32(h) 161 ii = float32(i) 162 return 163 } 164 165 func integer2floatConversions(t *testing.T) { 166 { 167 a, b, c, d, e, f, g, h, i := conv2Float64_ssa(0, 0, 0, 0, 0, 0, 0, 0, 0) 168 expectAll64(t, "zero64", 0, a, b, c, d, e, f, g, h, i) 169 } 170 { 171 a, b, c, d, e, f, g, h, i := conv2Float64_ssa(1, 1, 1, 1, 1, 1, 1, 1, 1) 172 expectAll64(t, "one64", 1, a, b, c, d, e, f, g, h, i) 173 } 174 { 175 a, b, c, d, e, f, g, h, i := conv2Float32_ssa(0, 0, 0, 0, 0, 0, 0, 0, 0) 176 expectAll32(t, "zero32", 0, a, b, c, d, e, f, g, h, i) 177 } 178 { 179 a, b, c, d, e, f, g, h, i := conv2Float32_ssa(1, 1, 1, 1, 1, 1, 1, 1, 1) 180 expectAll32(t, "one32", 1, a, b, c, d, e, f, g, h, i) 181 } 182 { 183 // Check maximum values 184 a, b, c, d, e, f, g, h, i := conv2Float64_ssa(127, 255, 32767, 65535, 0x7fffffff, 0xffffffff, 0x7fffFFFFffffFFFF, 0xffffFFFFffffFFFF, 3.402823e38) 185 expect64(t, "a", a, 127) 186 expect64(t, "b", b, 255) 187 expect64(t, "c", c, 32767) 188 expect64(t, "d", d, 65535) 189 expect64(t, "e", e, float64(int32(0x7fffffff))) 190 expect64(t, "f", f, float64(uint32(0xffffffff))) 191 expect64(t, "g", g, float64(int64(0x7fffffffffffffff))) 192 expect64(t, "h", h, float64(uint64(0xffffffffffffffff))) 193 expect64(t, "i", i, float64(float32(3.402823e38))) 194 } 195 { 196 // Check minimum values (and tweaks for unsigned) 197 a, b, c, d, e, f, g, h, i := conv2Float64_ssa(-128, 254, -32768, 65534, ^0x7fffffff, 0xfffffffe, ^0x7fffFFFFffffFFFF, 0xffffFFFFffffF401, 1.5e-45) 198 expect64(t, "a", a, -128) 199 expect64(t, "b", b, 254) 200 expect64(t, "c", c, -32768) 201 expect64(t, "d", d, 65534) 202 expect64(t, "e", e, float64(^int32(0x7fffffff))) 203 expect64(t, "f", f, float64(uint32(0xfffffffe))) 204 expect64(t, "g", g, float64(^int64(0x7fffffffffffffff))) 205 expect64(t, "h", h, float64(uint64(0xfffffffffffff401))) 206 expect64(t, "i", i, float64(float32(1.5e-45))) 207 } 208 { 209 // Check maximum values 210 a, b, c, d, e, f, g, h, i := conv2Float32_ssa(127, 255, 32767, 65535, 0x7fffffff, 0xffffffff, 0x7fffFFFFffffFFFF, 0xffffFFFFffffFFFF, 3.402823e38) 211 expect32(t, "a", a, 127) 212 expect32(t, "b", b, 255) 213 expect32(t, "c", c, 32767) 214 expect32(t, "d", d, 65535) 215 expect32(t, "e", e, float32(int32(0x7fffffff))) 216 expect32(t, "f", f, float32(uint32(0xffffffff))) 217 expect32(t, "g", g, float32(int64(0x7fffffffffffffff))) 218 expect32(t, "h", h, float32(uint64(0xffffffffffffffff))) 219 expect32(t, "i", i, float32(float64(3.402823e38))) 220 } 221 { 222 // Check minimum values (and tweaks for unsigned) 223 a, b, c, d, e, f, g, h, i := conv2Float32_ssa(-128, 254, -32768, 65534, ^0x7fffffff, 0xfffffffe, ^0x7fffFFFFffffFFFF, 0xffffFFFFffffF401, 1.5e-45) 224 expect32(t, "a", a, -128) 225 expect32(t, "b", b, 254) 226 expect32(t, "c", c, -32768) 227 expect32(t, "d", d, 65534) 228 expect32(t, "e", e, float32(^int32(0x7fffffff))) 229 expect32(t, "f", f, float32(uint32(0xfffffffe))) 230 expect32(t, "g", g, float32(^int64(0x7fffffffffffffff))) 231 expect32(t, "h", h, float32(uint64(0xfffffffffffff401))) 232 expect32(t, "i", i, float32(float64(1.5e-45))) 233 } 234 } 235 236 func multiplyAdd(t *testing.T) { 237 { 238 // Test that a multiply-accumulate operation with intermediate 239 // rounding forced by a float32() cast produces the expected 240 // result. 241 // Test cases generated experimentally on a system (s390x) that 242 // supports fused multiply-add instructions. 243 var tests = [...]struct{ x, y, z, res float32 }{ 244 {0.6046603, 0.9405091, 0.6645601, 1.2332485}, // fused multiply-add result: 1.2332486 245 {0.67908466, 0.21855305, 0.20318687, 0.3516029}, // fused multiply-add result: 0.35160288 246 {0.29311424, 0.29708257, 0.752573, 0.8396522}, // fused multiply-add result: 0.8396521 247 {0.5305857, 0.2535405, 0.282081, 0.41660595}, // fused multiply-add result: 0.41660598 248 {0.29711226, 0.89436173, 0.097454615, 0.36318043}, // fused multiply-add result: 0.36318046 249 {0.6810783, 0.24151509, 0.31152245, 0.47601312}, // fused multiply-add result: 0.47601315 250 {0.73023146, 0.18292491, 0.4283571, 0.5619346}, // fused multiply-add result: 0.56193465 251 {0.89634174, 0.32208398, 0.7211478, 1.009845}, // fused multiply-add result: 1.0098451 252 {0.6280982, 0.12675293, 0.2813303, 0.36094356}, // fused multiply-add result: 0.3609436 253 {0.29400632, 0.75316125, 0.15096405, 0.3723982}, // fused multiply-add result: 0.37239823 254 } 255 check := func(s string, got, expected float32) { 256 if got != expected { 257 fmt.Printf("multiplyAdd: %s, expected %g, got %g\n", s, expected, got) 258 } 259 } 260 for _, t := range tests { 261 check( 262 fmt.Sprintf("float32(%v * %v) + %v", t.x, t.y, t.z), 263 func(x, y, z float32) float32 { 264 return float32(x*y) + z 265 }(t.x, t.y, t.z), 266 t.res) 267 268 check( 269 fmt.Sprintf("%v += float32(%v * %v)", t.z, t.x, t.y), 270 func(x, y, z float32) float32 { 271 z += float32(x * y) 272 return z 273 }(t.x, t.y, t.z), 274 t.res) 275 } 276 } 277 { 278 // Test that a multiply-accumulate operation with intermediate 279 // rounding forced by a float64() cast produces the expected 280 // result. 281 // Test cases generated experimentally on a system (s390x) that 282 // supports fused multiply-add instructions. 283 var tests = [...]struct{ x, y, z, res float64 }{ 284 {0.4688898449024232, 0.28303415118044517, 0.29310185733681576, 0.42581369658590373}, // fused multiply-add result: 0.4258136965859037 285 {0.7886049150193449, 0.3618054804803169, 0.8805431227416171, 1.1658647029293308}, // fused multiply-add result: 1.1658647029293305 286 {0.7302314772948083, 0.18292491645390843, 0.4283570818068078, 0.5619346137829748}, // fused multiply-add result: 0.5619346137829747 287 {0.6908388315056789, 0.7109071952999951, 0.5637795958152644, 1.0549018919252924}, // fused multiply-add result: 1.0549018919252926 288 {0.4584424785756506, 0.6001655953233308, 0.02626515060968944, 0.3014065536855481}, // fused multiply-add result: 0.30140655368554814 289 {0.539210105890946, 0.9756748149873165, 0.7507630564795985, 1.2768567767840384}, // fused multiply-add result: 1.2768567767840386 290 {0.7830349733960021, 0.3932509992288867, 0.1304138461737918, 0.4383431318929343}, // fused multiply-add result: 0.43834313189293433 291 {0.6841751300974551, 0.6530402051353608, 0.524499759549865, 0.9712936268572192}, // fused multiply-add result: 0.9712936268572193 292 {0.3691117091643448, 0.826454125634742, 0.34768170859156955, 0.6527356034505334}, // fused multiply-add result: 0.6527356034505333 293 {0.16867966833433606, 0.33136826030698385, 0.8279280961505588, 0.8838231843956668}, // fused multiply-add result: 0.8838231843956669 294 } 295 check := func(s string, got, expected float64) { 296 if got != expected { 297 fmt.Printf("multiplyAdd: %s, expected %g, got %g\n", s, expected, got) 298 } 299 } 300 for _, t := range tests { 301 check( 302 fmt.Sprintf("float64(%v * %v) + %v", t.x, t.y, t.z), 303 func(x, y, z float64) float64 { 304 return float64(x*y) + z 305 }(t.x, t.y, t.z), 306 t.res) 307 308 check( 309 fmt.Sprintf("%v += float64(%v * %v)", t.z, t.x, t.y), 310 func(x, y, z float64) float64 { 311 z += float64(x * y) 312 return z 313 }(t.x, t.y, t.z), 314 t.res) 315 } 316 } 317 { 318 // Test that a multiply-accumulate operation with intermediate 319 // rounding forced by a complex128() cast produces the expected 320 // result. 321 // Test cases generated experimentally on a system (s390x) that 322 // supports fused multiply-add instructions. 323 var tests = [...]struct { 324 x, y float64 325 res complex128 326 }{ 327 {0.6046602879796196, 0.9405090880450124, (2.754489951983871 + 3i)}, // fused multiply-add result: (2.7544899519838713 + 3i) 328 {0.09696951891448456, 0.30091186058528707, (0.5918204173287407 + 3i)}, // fused multiply-add result: (0.5918204173287408 + 3i) 329 {0.544155573000885, 0.27850762181610883, (1.910974340818764 + 3i)}, // fused multiply-add result: (1.9109743408187638 + 3i) 330 {0.9769168685862624, 0.07429099894984302, (3.0050416047086297 + 3i)}, // fused multiply-add result: (3.00504160470863 + 3i) 331 {0.9269868035744142, 0.9549454404167818, (3.735905851140024 + 3i)}, // fused multiply-add result: (3.7359058511400245 + 3i) 332 {0.7109071952999951, 0.5637795958152644, (2.69650118171525 + 3i)}, // fused multiply-add result: (2.6965011817152496 + 3i) 333 {0.7558235074915978, 0.40380328579570035, (2.671273808270494 + 3i)}, // fused multiply-add result: (2.6712738082704934 + 3i) 334 {0.13065111702897217, 0.9859647293402467, (1.3779180804271633 + 3i)}, // fused multiply-add result: (1.3779180804271631 + 3i) 335 {0.8963417453962161, 0.3220839705208817, (3.0111092067095298 + 3i)}, // fused multiply-add result: (3.01110920670953 + 3i) 336 {0.39998376285699544, 0.497868113342702, (1.697819401913688 + 3i)}, // fused multiply-add result: (1.6978194019136883 + 3i) 337 } 338 check := func(s string, got, expected complex128) { 339 if got != expected { 340 fmt.Printf("multiplyAdd: %s, expected %v, got %v\n", s, expected, got) 341 } 342 } 343 for _, t := range tests { 344 check( 345 fmt.Sprintf("complex128(complex(%v, 1)*3) + complex(%v, 0)", t.x, t.y), 346 func(x, y float64) complex128 { 347 return complex128(complex(x, 1)*3) + complex(y, 0) 348 }(t.x, t.y), 349 t.res) 350 351 check( 352 fmt.Sprintf("z := complex(%v, 1); z += complex128(complex(%v, 1) * 3)", t.y, t.x), 353 func(x, y float64) complex128 { 354 z := complex(y, 0) 355 z += complex128(complex(x, 1) * 3) 356 return z 357 }(t.x, t.y), 358 t.res) 359 } 360 } 361 } 362 363 const ( 364 aa = 0x1000000000000000 365 ab = 0x100000000000000 366 ac = 0x10000000000000 367 ad = 0x1000000000000 368 ba = 0x100000000000 369 bb = 0x10000000000 370 bc = 0x1000000000 371 bd = 0x100000000 372 ca = 0x10000000 373 cb = 0x1000000 374 cc = 0x100000 375 cd = 0x10000 376 da = 0x1000 377 db = 0x100 378 dc = 0x10 379 dd = 0x1 380 ) 381 382 //go:noinline 383 func compares64_ssa(a, b, c, d float64) (lt, le, eq, ne, ge, gt uint64) { 384 if a < a { 385 lt += aa 386 } 387 if a < b { 388 lt += ab 389 } 390 if a < c { 391 lt += ac 392 } 393 if a < d { 394 lt += ad 395 } 396 397 if b < a { 398 lt += ba 399 } 400 if b < b { 401 lt += bb 402 } 403 if b < c { 404 lt += bc 405 } 406 if b < d { 407 lt += bd 408 } 409 410 if c < a { 411 lt += ca 412 } 413 if c < b { 414 lt += cb 415 } 416 if c < c { 417 lt += cc 418 } 419 if c < d { 420 lt += cd 421 } 422 423 if d < a { 424 lt += da 425 } 426 if d < b { 427 lt += db 428 } 429 if d < c { 430 lt += dc 431 } 432 if d < d { 433 lt += dd 434 } 435 436 if a <= a { 437 le += aa 438 } 439 if a <= b { 440 le += ab 441 } 442 if a <= c { 443 le += ac 444 } 445 if a <= d { 446 le += ad 447 } 448 449 if b <= a { 450 le += ba 451 } 452 if b <= b { 453 le += bb 454 } 455 if b <= c { 456 le += bc 457 } 458 if b <= d { 459 le += bd 460 } 461 462 if c <= a { 463 le += ca 464 } 465 if c <= b { 466 le += cb 467 } 468 if c <= c { 469 le += cc 470 } 471 if c <= d { 472 le += cd 473 } 474 475 if d <= a { 476 le += da 477 } 478 if d <= b { 479 le += db 480 } 481 if d <= c { 482 le += dc 483 } 484 if d <= d { 485 le += dd 486 } 487 488 if a == a { 489 eq += aa 490 } 491 if a == b { 492 eq += ab 493 } 494 if a == c { 495 eq += ac 496 } 497 if a == d { 498 eq += ad 499 } 500 501 if b == a { 502 eq += ba 503 } 504 if b == b { 505 eq += bb 506 } 507 if b == c { 508 eq += bc 509 } 510 if b == d { 511 eq += bd 512 } 513 514 if c == a { 515 eq += ca 516 } 517 if c == b { 518 eq += cb 519 } 520 if c == c { 521 eq += cc 522 } 523 if c == d { 524 eq += cd 525 } 526 527 if d == a { 528 eq += da 529 } 530 if d == b { 531 eq += db 532 } 533 if d == c { 534 eq += dc 535 } 536 if d == d { 537 eq += dd 538 } 539 540 if a != a { 541 ne += aa 542 } 543 if a != b { 544 ne += ab 545 } 546 if a != c { 547 ne += ac 548 } 549 if a != d { 550 ne += ad 551 } 552 553 if b != a { 554 ne += ba 555 } 556 if b != b { 557 ne += bb 558 } 559 if b != c { 560 ne += bc 561 } 562 if b != d { 563 ne += bd 564 } 565 566 if c != a { 567 ne += ca 568 } 569 if c != b { 570 ne += cb 571 } 572 if c != c { 573 ne += cc 574 } 575 if c != d { 576 ne += cd 577 } 578 579 if d != a { 580 ne += da 581 } 582 if d != b { 583 ne += db 584 } 585 if d != c { 586 ne += dc 587 } 588 if d != d { 589 ne += dd 590 } 591 592 if a >= a { 593 ge += aa 594 } 595 if a >= b { 596 ge += ab 597 } 598 if a >= c { 599 ge += ac 600 } 601 if a >= d { 602 ge += ad 603 } 604 605 if b >= a { 606 ge += ba 607 } 608 if b >= b { 609 ge += bb 610 } 611 if b >= c { 612 ge += bc 613 } 614 if b >= d { 615 ge += bd 616 } 617 618 if c >= a { 619 ge += ca 620 } 621 if c >= b { 622 ge += cb 623 } 624 if c >= c { 625 ge += cc 626 } 627 if c >= d { 628 ge += cd 629 } 630 631 if d >= a { 632 ge += da 633 } 634 if d >= b { 635 ge += db 636 } 637 if d >= c { 638 ge += dc 639 } 640 if d >= d { 641 ge += dd 642 } 643 644 if a > a { 645 gt += aa 646 } 647 if a > b { 648 gt += ab 649 } 650 if a > c { 651 gt += ac 652 } 653 if a > d { 654 gt += ad 655 } 656 657 if b > a { 658 gt += ba 659 } 660 if b > b { 661 gt += bb 662 } 663 if b > c { 664 gt += bc 665 } 666 if b > d { 667 gt += bd 668 } 669 670 if c > a { 671 gt += ca 672 } 673 if c > b { 674 gt += cb 675 } 676 if c > c { 677 gt += cc 678 } 679 if c > d { 680 gt += cd 681 } 682 683 if d > a { 684 gt += da 685 } 686 if d > b { 687 gt += db 688 } 689 if d > c { 690 gt += dc 691 } 692 if d > d { 693 gt += dd 694 } 695 696 return 697 } 698 699 //go:noinline 700 func compares32_ssa(a, b, c, d float32) (lt, le, eq, ne, ge, gt uint64) { 701 if a < a { 702 lt += aa 703 } 704 if a < b { 705 lt += ab 706 } 707 if a < c { 708 lt += ac 709 } 710 if a < d { 711 lt += ad 712 } 713 714 if b < a { 715 lt += ba 716 } 717 if b < b { 718 lt += bb 719 } 720 if b < c { 721 lt += bc 722 } 723 if b < d { 724 lt += bd 725 } 726 727 if c < a { 728 lt += ca 729 } 730 if c < b { 731 lt += cb 732 } 733 if c < c { 734 lt += cc 735 } 736 if c < d { 737 lt += cd 738 } 739 740 if d < a { 741 lt += da 742 } 743 if d < b { 744 lt += db 745 } 746 if d < c { 747 lt += dc 748 } 749 if d < d { 750 lt += dd 751 } 752 753 if a <= a { 754 le += aa 755 } 756 if a <= b { 757 le += ab 758 } 759 if a <= c { 760 le += ac 761 } 762 if a <= d { 763 le += ad 764 } 765 766 if b <= a { 767 le += ba 768 } 769 if b <= b { 770 le += bb 771 } 772 if b <= c { 773 le += bc 774 } 775 if b <= d { 776 le += bd 777 } 778 779 if c <= a { 780 le += ca 781 } 782 if c <= b { 783 le += cb 784 } 785 if c <= c { 786 le += cc 787 } 788 if c <= d { 789 le += cd 790 } 791 792 if d <= a { 793 le += da 794 } 795 if d <= b { 796 le += db 797 } 798 if d <= c { 799 le += dc 800 } 801 if d <= d { 802 le += dd 803 } 804 805 if a == a { 806 eq += aa 807 } 808 if a == b { 809 eq += ab 810 } 811 if a == c { 812 eq += ac 813 } 814 if a == d { 815 eq += ad 816 } 817 818 if b == a { 819 eq += ba 820 } 821 if b == b { 822 eq += bb 823 } 824 if b == c { 825 eq += bc 826 } 827 if b == d { 828 eq += bd 829 } 830 831 if c == a { 832 eq += ca 833 } 834 if c == b { 835 eq += cb 836 } 837 if c == c { 838 eq += cc 839 } 840 if c == d { 841 eq += cd 842 } 843 844 if d == a { 845 eq += da 846 } 847 if d == b { 848 eq += db 849 } 850 if d == c { 851 eq += dc 852 } 853 if d == d { 854 eq += dd 855 } 856 857 if a != a { 858 ne += aa 859 } 860 if a != b { 861 ne += ab 862 } 863 if a != c { 864 ne += ac 865 } 866 if a != d { 867 ne += ad 868 } 869 870 if b != a { 871 ne += ba 872 } 873 if b != b { 874 ne += bb 875 } 876 if b != c { 877 ne += bc 878 } 879 if b != d { 880 ne += bd 881 } 882 883 if c != a { 884 ne += ca 885 } 886 if c != b { 887 ne += cb 888 } 889 if c != c { 890 ne += cc 891 } 892 if c != d { 893 ne += cd 894 } 895 896 if d != a { 897 ne += da 898 } 899 if d != b { 900 ne += db 901 } 902 if d != c { 903 ne += dc 904 } 905 if d != d { 906 ne += dd 907 } 908 909 if a >= a { 910 ge += aa 911 } 912 if a >= b { 913 ge += ab 914 } 915 if a >= c { 916 ge += ac 917 } 918 if a >= d { 919 ge += ad 920 } 921 922 if b >= a { 923 ge += ba 924 } 925 if b >= b { 926 ge += bb 927 } 928 if b >= c { 929 ge += bc 930 } 931 if b >= d { 932 ge += bd 933 } 934 935 if c >= a { 936 ge += ca 937 } 938 if c >= b { 939 ge += cb 940 } 941 if c >= c { 942 ge += cc 943 } 944 if c >= d { 945 ge += cd 946 } 947 948 if d >= a { 949 ge += da 950 } 951 if d >= b { 952 ge += db 953 } 954 if d >= c { 955 ge += dc 956 } 957 if d >= d { 958 ge += dd 959 } 960 961 if a > a { 962 gt += aa 963 } 964 if a > b { 965 gt += ab 966 } 967 if a > c { 968 gt += ac 969 } 970 if a > d { 971 gt += ad 972 } 973 974 if b > a { 975 gt += ba 976 } 977 if b > b { 978 gt += bb 979 } 980 if b > c { 981 gt += bc 982 } 983 if b > d { 984 gt += bd 985 } 986 987 if c > a { 988 gt += ca 989 } 990 if c > b { 991 gt += cb 992 } 993 if c > c { 994 gt += cc 995 } 996 if c > d { 997 gt += cd 998 } 999 1000 if d > a { 1001 gt += da 1002 } 1003 if d > b { 1004 gt += db 1005 } 1006 if d > c { 1007 gt += dc 1008 } 1009 if d > d { 1010 gt += dd 1011 } 1012 1013 return 1014 } 1015 1016 //go:noinline 1017 func le64_ssa(x, y float64) bool { 1018 return x <= y 1019 } 1020 1021 //go:noinline 1022 func ge64_ssa(x, y float64) bool { 1023 return x >= y 1024 } 1025 1026 //go:noinline 1027 func lt64_ssa(x, y float64) bool { 1028 return x < y 1029 } 1030 1031 //go:noinline 1032 func gt64_ssa(x, y float64) bool { 1033 return x > y 1034 } 1035 1036 //go:noinline 1037 func eq64_ssa(x, y float64) bool { 1038 return x == y 1039 } 1040 1041 //go:noinline 1042 func ne64_ssa(x, y float64) bool { 1043 return x != y 1044 } 1045 1046 //go:noinline 1047 func eqbr64_ssa(x, y float64) float64 { 1048 if x == y { 1049 return 17 1050 } 1051 return 42 1052 } 1053 1054 //go:noinline 1055 func nebr64_ssa(x, y float64) float64 { 1056 if x != y { 1057 return 17 1058 } 1059 return 42 1060 } 1061 1062 //go:noinline 1063 func gebr64_ssa(x, y float64) float64 { 1064 if x >= y { 1065 return 17 1066 } 1067 return 42 1068 } 1069 1070 //go:noinline 1071 func lebr64_ssa(x, y float64) float64 { 1072 if x <= y { 1073 return 17 1074 } 1075 return 42 1076 } 1077 1078 //go:noinline 1079 func ltbr64_ssa(x, y float64) float64 { 1080 if x < y { 1081 return 17 1082 } 1083 return 42 1084 } 1085 1086 //go:noinline 1087 func gtbr64_ssa(x, y float64) float64 { 1088 if x > y { 1089 return 17 1090 } 1091 return 42 1092 } 1093 1094 //go:noinline 1095 func le32_ssa(x, y float32) bool { 1096 return x <= y 1097 } 1098 1099 //go:noinline 1100 func ge32_ssa(x, y float32) bool { 1101 return x >= y 1102 } 1103 1104 //go:noinline 1105 func lt32_ssa(x, y float32) bool { 1106 return x < y 1107 } 1108 1109 //go:noinline 1110 func gt32_ssa(x, y float32) bool { 1111 return x > y 1112 } 1113 1114 //go:noinline 1115 func eq32_ssa(x, y float32) bool { 1116 return x == y 1117 } 1118 1119 //go:noinline 1120 func ne32_ssa(x, y float32) bool { 1121 return x != y 1122 } 1123 1124 //go:noinline 1125 func eqbr32_ssa(x, y float32) float32 { 1126 if x == y { 1127 return 17 1128 } 1129 return 42 1130 } 1131 1132 //go:noinline 1133 func nebr32_ssa(x, y float32) float32 { 1134 if x != y { 1135 return 17 1136 } 1137 return 42 1138 } 1139 1140 //go:noinline 1141 func gebr32_ssa(x, y float32) float32 { 1142 if x >= y { 1143 return 17 1144 } 1145 return 42 1146 } 1147 1148 //go:noinline 1149 func lebr32_ssa(x, y float32) float32 { 1150 if x <= y { 1151 return 17 1152 } 1153 return 42 1154 } 1155 1156 //go:noinline 1157 func ltbr32_ssa(x, y float32) float32 { 1158 if x < y { 1159 return 17 1160 } 1161 return 42 1162 } 1163 1164 //go:noinline 1165 func gtbr32_ssa(x, y float32) float32 { 1166 if x > y { 1167 return 17 1168 } 1169 return 42 1170 } 1171 1172 //go:noinline 1173 func F32toU8_ssa(x float32) uint8 { 1174 return uint8(x) 1175 } 1176 1177 //go:noinline 1178 func F32toI8_ssa(x float32) int8 { 1179 return int8(x) 1180 } 1181 1182 //go:noinline 1183 func F32toU16_ssa(x float32) uint16 { 1184 return uint16(x) 1185 } 1186 1187 //go:noinline 1188 func F32toI16_ssa(x float32) int16 { 1189 return int16(x) 1190 } 1191 1192 //go:noinline 1193 func F32toU32_ssa(x float32) uint32 { 1194 return uint32(x) 1195 } 1196 1197 //go:noinline 1198 func F32toI32_ssa(x float32) int32 { 1199 return int32(x) 1200 } 1201 1202 //go:noinline 1203 func F32toU64_ssa(x float32) uint64 { 1204 return uint64(x) 1205 } 1206 1207 //go:noinline 1208 func F32toI64_ssa(x float32) int64 { 1209 return int64(x) 1210 } 1211 1212 //go:noinline 1213 func F64toU8_ssa(x float64) uint8 { 1214 return uint8(x) 1215 } 1216 1217 //go:noinline 1218 func F64toI8_ssa(x float64) int8 { 1219 return int8(x) 1220 } 1221 1222 //go:noinline 1223 func F64toU16_ssa(x float64) uint16 { 1224 return uint16(x) 1225 } 1226 1227 //go:noinline 1228 func F64toI16_ssa(x float64) int16 { 1229 return int16(x) 1230 } 1231 1232 //go:noinline 1233 func F64toU32_ssa(x float64) uint32 { 1234 return uint32(x) 1235 } 1236 1237 //go:noinline 1238 func F64toI32_ssa(x float64) int32 { 1239 return int32(x) 1240 } 1241 1242 //go:noinline 1243 func F64toU64_ssa(x float64) uint64 { 1244 return uint64(x) 1245 } 1246 1247 //go:noinline 1248 func F64toI64_ssa(x float64) int64 { 1249 return int64(x) 1250 } 1251 1252 func floatsToInts(t *testing.T, x float64, expected int64) { 1253 y := float32(x) 1254 expectInt64(t, "F64toI8", int64(F64toI8_ssa(x)), expected) 1255 expectInt64(t, "F64toI16", int64(F64toI16_ssa(x)), expected) 1256 expectInt64(t, "F64toI32", int64(F64toI32_ssa(x)), expected) 1257 expectInt64(t, "F64toI64", int64(F64toI64_ssa(x)), expected) 1258 expectInt64(t, "F32toI8", int64(F32toI8_ssa(y)), expected) 1259 expectInt64(t, "F32toI16", int64(F32toI16_ssa(y)), expected) 1260 expectInt64(t, "F32toI32", int64(F32toI32_ssa(y)), expected) 1261 expectInt64(t, "F32toI64", int64(F32toI64_ssa(y)), expected) 1262 } 1263 1264 func floatsToUints(t *testing.T, x float64, expected uint64) { 1265 y := float32(x) 1266 expectUint64(t, "F64toU8", uint64(F64toU8_ssa(x)), expected) 1267 expectUint64(t, "F64toU16", uint64(F64toU16_ssa(x)), expected) 1268 expectUint64(t, "F64toU32", uint64(F64toU32_ssa(x)), expected) 1269 expectUint64(t, "F64toU64", uint64(F64toU64_ssa(x)), expected) 1270 expectUint64(t, "F32toU8", uint64(F32toU8_ssa(y)), expected) 1271 expectUint64(t, "F32toU16", uint64(F32toU16_ssa(y)), expected) 1272 expectUint64(t, "F32toU32", uint64(F32toU32_ssa(y)), expected) 1273 expectUint64(t, "F32toU64", uint64(F32toU64_ssa(y)), expected) 1274 } 1275 1276 func floatingToIntegerConversionsTest(t *testing.T) { 1277 floatsToInts(t, 0.0, 0) 1278 floatsToInts(t, 0.5, 0) 1279 floatsToInts(t, 0.9, 0) 1280 floatsToInts(t, 1.0, 1) 1281 floatsToInts(t, 1.5, 1) 1282 floatsToInts(t, 127.0, 127) 1283 floatsToInts(t, -1.0, -1) 1284 floatsToInts(t, -128.0, -128) 1285 1286 floatsToUints(t, 0.0, 0) 1287 floatsToUints(t, 1.0, 1) 1288 floatsToUints(t, 255.0, 255) 1289 1290 for j := uint(0); j < 24; j++ { 1291 // Avoid hard cases in the construction 1292 // of the test inputs. 1293 v := int64(1<<62) | int64(1<<(62-j)) 1294 w := uint64(v) 1295 f := float32(v) 1296 d := float64(v) 1297 expectUint64(t, "2**62...", F32toU64_ssa(f), w) 1298 expectUint64(t, "2**62...", F64toU64_ssa(d), w) 1299 expectInt64(t, "2**62...", F32toI64_ssa(f), v) 1300 expectInt64(t, "2**62...", F64toI64_ssa(d), v) 1301 expectInt64(t, "2**62...", F32toI64_ssa(-f), -v) 1302 expectInt64(t, "2**62...", F64toI64_ssa(-d), -v) 1303 w += w 1304 f += f 1305 d += d 1306 expectUint64(t, "2**63...", F32toU64_ssa(f), w) 1307 expectUint64(t, "2**63...", F64toU64_ssa(d), w) 1308 } 1309 1310 for j := uint(0); j < 16; j++ { 1311 // Avoid hard cases in the construction 1312 // of the test inputs. 1313 v := int32(1<<30) | int32(1<<(30-j)) 1314 w := uint32(v) 1315 f := float32(v) 1316 d := float64(v) 1317 expectUint32(t, "2**30...", F32toU32_ssa(f), w) 1318 expectUint32(t, "2**30...", F64toU32_ssa(d), w) 1319 expectInt32(t, "2**30...", F32toI32_ssa(f), v) 1320 expectInt32(t, "2**30...", F64toI32_ssa(d), v) 1321 expectInt32(t, "2**30...", F32toI32_ssa(-f), -v) 1322 expectInt32(t, "2**30...", F64toI32_ssa(-d), -v) 1323 w += w 1324 f += f 1325 d += d 1326 expectUint32(t, "2**31...", F32toU32_ssa(f), w) 1327 expectUint32(t, "2**31...", F64toU32_ssa(d), w) 1328 } 1329 1330 for j := uint(0); j < 15; j++ { 1331 // Avoid hard cases in the construction 1332 // of the test inputs. 1333 v := int16(1<<14) | int16(1<<(14-j)) 1334 w := uint16(v) 1335 f := float32(v) 1336 d := float64(v) 1337 expectUint16(t, "2**14...", F32toU16_ssa(f), w) 1338 expectUint16(t, "2**14...", F64toU16_ssa(d), w) 1339 expectInt16(t, "2**14...", F32toI16_ssa(f), v) 1340 expectInt16(t, "2**14...", F64toI16_ssa(d), v) 1341 expectInt16(t, "2**14...", F32toI16_ssa(-f), -v) 1342 expectInt16(t, "2**14...", F64toI16_ssa(-d), -v) 1343 w += w 1344 f += f 1345 d += d 1346 expectUint16(t, "2**15...", F32toU16_ssa(f), w) 1347 expectUint16(t, "2**15...", F64toU16_ssa(d), w) 1348 } 1349 1350 expectInt32(t, "-2147483648", F32toI32_ssa(-2147483648), -2147483648) 1351 1352 expectInt32(t, "-2147483648", F64toI32_ssa(-2147483648), -2147483648) 1353 expectInt32(t, "-2147483647", F64toI32_ssa(-2147483647), -2147483647) 1354 expectUint32(t, "4294967295", F64toU32_ssa(4294967295), 4294967295) 1355 1356 expectInt16(t, "-32768", F64toI16_ssa(-32768), -32768) 1357 expectInt16(t, "-32768", F32toI16_ssa(-32768), -32768) 1358 1359 // NB more of a pain to do these for 32-bit because of lost bits in Float32 mantissa 1360 expectInt16(t, "32767", F64toI16_ssa(32767), 32767) 1361 expectInt16(t, "32767", F32toI16_ssa(32767), 32767) 1362 expectUint16(t, "32767", F64toU16_ssa(32767), 32767) 1363 expectUint16(t, "32767", F32toU16_ssa(32767), 32767) 1364 expectUint16(t, "65535", F64toU16_ssa(65535), 65535) 1365 expectUint16(t, "65535", F32toU16_ssa(65535), 65535) 1366 } 1367 1368 func fail64(s string, f func(a, b float64) float64, a, b, e float64) { 1369 d := f(a, b) 1370 if d != e { 1371 fmt.Printf("For (float64) %v %v %v, expected %v, got %v\n", a, s, b, e, d) 1372 } 1373 } 1374 1375 func fail64bool(s string, f func(a, b float64) bool, a, b float64, e bool) { 1376 d := f(a, b) 1377 if d != e { 1378 fmt.Printf("For (float64) %v %v %v, expected %v, got %v\n", a, s, b, e, d) 1379 } 1380 } 1381 1382 func fail32(s string, f func(a, b float32) float32, a, b, e float32) { 1383 d := f(a, b) 1384 if d != e { 1385 fmt.Printf("For (float32) %v %v %v, expected %v, got %v\n", a, s, b, e, d) 1386 } 1387 } 1388 1389 func fail32bool(s string, f func(a, b float32) bool, a, b float32, e bool) { 1390 d := f(a, b) 1391 if d != e { 1392 fmt.Printf("For (float32) %v %v %v, expected %v, got %v\n", a, s, b, e, d) 1393 } 1394 } 1395 1396 func expect64(t *testing.T, s string, x, expected float64) { 1397 if x != expected { 1398 println("F64 Expected", expected, "for", s, ", got", x) 1399 } 1400 } 1401 1402 func expect32(t *testing.T, s string, x, expected float32) { 1403 if x != expected { 1404 println("F32 Expected", expected, "for", s, ", got", x) 1405 } 1406 } 1407 1408 func expectUint64(t *testing.T, s string, x, expected uint64) { 1409 if x != expected { 1410 fmt.Printf("U64 Expected 0x%016x for %s, got 0x%016x\n", expected, s, x) 1411 } 1412 } 1413 1414 func expectInt64(t *testing.T, s string, x, expected int64) { 1415 if x != expected { 1416 fmt.Printf("%s: Expected 0x%016x, got 0x%016x\n", s, expected, x) 1417 } 1418 } 1419 1420 func expectUint32(t *testing.T, s string, x, expected uint32) { 1421 if x != expected { 1422 fmt.Printf("U32 %s: Expected 0x%08x, got 0x%08x\n", s, expected, x) 1423 } 1424 } 1425 1426 func expectInt32(t *testing.T, s string, x, expected int32) { 1427 if x != expected { 1428 fmt.Printf("I32 %s: Expected 0x%08x, got 0x%08x\n", s, expected, x) 1429 } 1430 } 1431 1432 func expectUint16(t *testing.T, s string, x, expected uint16) { 1433 if x != expected { 1434 fmt.Printf("U16 %s: Expected 0x%04x, got 0x%04x\n", s, expected, x) 1435 } 1436 } 1437 1438 func expectInt16(t *testing.T, s string, x, expected int16) { 1439 if x != expected { 1440 fmt.Printf("I16 %s: Expected 0x%04x, got 0x%04x\n", s, expected, x) 1441 } 1442 } 1443 1444 func expectAll64(t *testing.T, s string, expected, a, b, c, d, e, f, g, h, i float64) { 1445 expect64(t, s+":a", a, expected) 1446 expect64(t, s+":b", b, expected) 1447 expect64(t, s+":c", c, expected) 1448 expect64(t, s+":d", d, expected) 1449 expect64(t, s+":e", e, expected) 1450 expect64(t, s+":f", f, expected) 1451 expect64(t, s+":g", g, expected) 1452 } 1453 1454 func expectAll32(t *testing.T, s string, expected, a, b, c, d, e, f, g, h, i float32) { 1455 expect32(t, s+":a", a, expected) 1456 expect32(t, s+":b", b, expected) 1457 expect32(t, s+":c", c, expected) 1458 expect32(t, s+":d", d, expected) 1459 expect32(t, s+":e", e, expected) 1460 expect32(t, s+":f", f, expected) 1461 expect32(t, s+":g", g, expected) 1462 } 1463 1464 var ev64 [2]float64 = [2]float64{42.0, 17.0} 1465 var ev32 [2]float32 = [2]float32{42.0, 17.0} 1466 1467 func cmpOpTest(t *testing.T, 1468 s string, 1469 f func(a, b float64) bool, 1470 g func(a, b float64) float64, 1471 ff func(a, b float32) bool, 1472 gg func(a, b float32) float32, 1473 zero, one, inf, nan float64, result uint) { 1474 fail64bool(s, f, zero, zero, result>>16&1 == 1) 1475 fail64bool(s, f, zero, one, result>>12&1 == 1) 1476 fail64bool(s, f, zero, inf, result>>8&1 == 1) 1477 fail64bool(s, f, zero, nan, result>>4&1 == 1) 1478 fail64bool(s, f, nan, nan, result&1 == 1) 1479 1480 fail64(s, g, zero, zero, ev64[result>>16&1]) 1481 fail64(s, g, zero, one, ev64[result>>12&1]) 1482 fail64(s, g, zero, inf, ev64[result>>8&1]) 1483 fail64(s, g, zero, nan, ev64[result>>4&1]) 1484 fail64(s, g, nan, nan, ev64[result>>0&1]) 1485 1486 { 1487 zero := float32(zero) 1488 one := float32(one) 1489 inf := float32(inf) 1490 nan := float32(nan) 1491 fail32bool(s, ff, zero, zero, (result>>16)&1 == 1) 1492 fail32bool(s, ff, zero, one, (result>>12)&1 == 1) 1493 fail32bool(s, ff, zero, inf, (result>>8)&1 == 1) 1494 fail32bool(s, ff, zero, nan, (result>>4)&1 == 1) 1495 fail32bool(s, ff, nan, nan, result&1 == 1) 1496 1497 fail32(s, gg, zero, zero, ev32[(result>>16)&1]) 1498 fail32(s, gg, zero, one, ev32[(result>>12)&1]) 1499 fail32(s, gg, zero, inf, ev32[(result>>8)&1]) 1500 fail32(s, gg, zero, nan, ev32[(result>>4)&1]) 1501 fail32(s, gg, nan, nan, ev32[(result>>0)&1]) 1502 } 1503 } 1504 1505 func expectCx128(t *testing.T, s string, x, expected complex128) { 1506 if x != expected { 1507 t.Errorf("Cx 128 Expected %f for %s, got %f", expected, s, x) 1508 } 1509 } 1510 1511 func expectCx64(t *testing.T, s string, x, expected complex64) { 1512 if x != expected { 1513 t.Errorf("Cx 64 Expected %f for %s, got %f", expected, s, x) 1514 } 1515 } 1516 1517 //go:noinline 1518 func cx128sum_ssa(a, b complex128) complex128 { 1519 return a + b 1520 } 1521 1522 //go:noinline 1523 func cx128diff_ssa(a, b complex128) complex128 { 1524 return a - b 1525 } 1526 1527 //go:noinline 1528 func cx128prod_ssa(a, b complex128) complex128 { 1529 return a * b 1530 } 1531 1532 //go:noinline 1533 func cx128quot_ssa(a, b complex128) complex128 { 1534 return a / b 1535 } 1536 1537 //go:noinline 1538 func cx128neg_ssa(a complex128) complex128 { 1539 return -a 1540 } 1541 1542 //go:noinline 1543 func cx128real_ssa(a complex128) float64 { 1544 return real(a) 1545 } 1546 1547 //go:noinline 1548 func cx128imag_ssa(a complex128) float64 { 1549 return imag(a) 1550 } 1551 1552 //go:noinline 1553 func cx128cnst_ssa(a complex128) complex128 { 1554 b := 2 + 3i 1555 return a * b 1556 } 1557 1558 //go:noinline 1559 func cx64sum_ssa(a, b complex64) complex64 { 1560 return a + b 1561 } 1562 1563 //go:noinline 1564 func cx64diff_ssa(a, b complex64) complex64 { 1565 return a - b 1566 } 1567 1568 //go:noinline 1569 func cx64prod_ssa(a, b complex64) complex64 { 1570 return a * b 1571 } 1572 1573 //go:noinline 1574 func cx64quot_ssa(a, b complex64) complex64 { 1575 return a / b 1576 } 1577 1578 //go:noinline 1579 func cx64neg_ssa(a complex64) complex64 { 1580 return -a 1581 } 1582 1583 //go:noinline 1584 func cx64real_ssa(a complex64) float32 { 1585 return real(a) 1586 } 1587 1588 //go:noinline 1589 func cx64imag_ssa(a complex64) float32 { 1590 return imag(a) 1591 } 1592 1593 //go:noinline 1594 func cx128eq_ssa(a, b complex128) bool { 1595 return a == b 1596 } 1597 1598 //go:noinline 1599 func cx128ne_ssa(a, b complex128) bool { 1600 return a != b 1601 } 1602 1603 //go:noinline 1604 func cx64eq_ssa(a, b complex64) bool { 1605 return a == b 1606 } 1607 1608 //go:noinline 1609 func cx64ne_ssa(a, b complex64) bool { 1610 return a != b 1611 } 1612 1613 func expectTrue(t *testing.T, s string, b bool) { 1614 if !b { 1615 t.Errorf("expected true for %s, got false", s) 1616 } 1617 } 1618 func expectFalse(t *testing.T, s string, b bool) { 1619 if b { 1620 t.Errorf("expected false for %s, got true", s) 1621 } 1622 } 1623 1624 func complexTest128(t *testing.T) { 1625 var a complex128 = 1 + 2i 1626 var b complex128 = 3 + 6i 1627 sum := cx128sum_ssa(b, a) 1628 diff := cx128diff_ssa(b, a) 1629 prod := cx128prod_ssa(b, a) 1630 quot := cx128quot_ssa(b, a) 1631 neg := cx128neg_ssa(a) 1632 r := cx128real_ssa(a) 1633 i := cx128imag_ssa(a) 1634 cnst := cx128cnst_ssa(a) 1635 c1 := cx128eq_ssa(a, a) 1636 c2 := cx128eq_ssa(a, b) 1637 c3 := cx128ne_ssa(a, a) 1638 c4 := cx128ne_ssa(a, b) 1639 1640 expectCx128(t, "sum", sum, 4+8i) 1641 expectCx128(t, "diff", diff, 2+4i) 1642 expectCx128(t, "prod", prod, -9+12i) 1643 expectCx128(t, "quot", quot, 3+0i) 1644 expectCx128(t, "neg", neg, -1-2i) 1645 expect64(t, "real", r, 1) 1646 expect64(t, "imag", i, 2) 1647 expectCx128(t, "cnst", cnst, -4+7i) 1648 expectTrue(t, fmt.Sprintf("%v==%v", a, a), c1) 1649 expectFalse(t, fmt.Sprintf("%v==%v", a, b), c2) 1650 expectFalse(t, fmt.Sprintf("%v!=%v", a, a), c3) 1651 expectTrue(t, fmt.Sprintf("%v!=%v", a, b), c4) 1652 } 1653 1654 func complexTest64(t *testing.T) { 1655 var a complex64 = 1 + 2i 1656 var b complex64 = 3 + 6i 1657 sum := cx64sum_ssa(b, a) 1658 diff := cx64diff_ssa(b, a) 1659 prod := cx64prod_ssa(b, a) 1660 quot := cx64quot_ssa(b, a) 1661 neg := cx64neg_ssa(a) 1662 r := cx64real_ssa(a) 1663 i := cx64imag_ssa(a) 1664 c1 := cx64eq_ssa(a, a) 1665 c2 := cx64eq_ssa(a, b) 1666 c3 := cx64ne_ssa(a, a) 1667 c4 := cx64ne_ssa(a, b) 1668 1669 expectCx64(t, "sum", sum, 4+8i) 1670 expectCx64(t, "diff", diff, 2+4i) 1671 expectCx64(t, "prod", prod, -9+12i) 1672 expectCx64(t, "quot", quot, 3+0i) 1673 expectCx64(t, "neg", neg, -1-2i) 1674 expect32(t, "real", r, 1) 1675 expect32(t, "imag", i, 2) 1676 expectTrue(t, fmt.Sprintf("%v==%v", a, a), c1) 1677 expectFalse(t, fmt.Sprintf("%v==%v", a, b), c2) 1678 expectFalse(t, fmt.Sprintf("%v!=%v", a, a), c3) 1679 expectTrue(t, fmt.Sprintf("%v!=%v", a, b), c4) 1680 } 1681 1682 // TestFP tests that we get the right answer for floating point expressions. 1683 func TestFP(t *testing.T) { 1684 a := 3.0 1685 b := 4.0 1686 1687 c := float32(3.0) 1688 d := float32(4.0) 1689 1690 tiny := float32(1.5e-45) // smallest f32 denorm = 2**(-149) 1691 dtiny := float64(tiny) // well within range of f64 1692 1693 fail64("+", add64_ssa, a, b, 7.0) 1694 fail64("*", mul64_ssa, a, b, 12.0) 1695 fail64("-", sub64_ssa, a, b, -1.0) 1696 fail64("/", div64_ssa, a, b, 0.75) 1697 fail64("neg", neg64_ssa, a, b, -7) 1698 1699 fail32("+", add32_ssa, c, d, 7.0) 1700 fail32("*", mul32_ssa, c, d, 12.0) 1701 fail32("-", sub32_ssa, c, d, -1.0) 1702 fail32("/", div32_ssa, c, d, 0.75) 1703 fail32("neg", neg32_ssa, c, d, -7) 1704 1705 // denorm-squared should underflow to zero. 1706 fail32("*", mul32_ssa, tiny, tiny, 0) 1707 1708 // but should not underflow in float and in fact is exactly representable. 1709 fail64("*", mul64_ssa, dtiny, dtiny, 1.9636373861190906e-90) 1710 1711 // Intended to create register pressure which forces 1712 // asymmetric op into different code paths. 1713 aa, ab, ac, ad, ba, bb, bc, bd, ca, cb, cc, cd, da, db, dc, dd := manysub_ssa(1000.0, 100.0, 10.0, 1.0) 1714 1715 expect64(t, "aa", aa, 11.0) 1716 expect64(t, "ab", ab, 900.0) 1717 expect64(t, "ac", ac, 990.0) 1718 expect64(t, "ad", ad, 999.0) 1719 1720 expect64(t, "ba", ba, -900.0) 1721 expect64(t, "bb", bb, 22.0) 1722 expect64(t, "bc", bc, 90.0) 1723 expect64(t, "bd", bd, 99.0) 1724 1725 expect64(t, "ca", ca, -990.0) 1726 expect64(t, "cb", cb, -90.0) 1727 expect64(t, "cc", cc, 33.0) 1728 expect64(t, "cd", cd, 9.0) 1729 1730 expect64(t, "da", da, -999.0) 1731 expect64(t, "db", db, -99.0) 1732 expect64(t, "dc", dc, -9.0) 1733 expect64(t, "dd", dd, 44.0) 1734 1735 integer2floatConversions(t) 1736 1737 multiplyAdd(t) 1738 1739 var zero64 float64 = 0.0 1740 var one64 float64 = 1.0 1741 var inf64 float64 = 1.0 / zero64 1742 var nan64 float64 = sub64_ssa(inf64, inf64) 1743 1744 cmpOpTest(t, "!=", ne64_ssa, nebr64_ssa, ne32_ssa, nebr32_ssa, zero64, one64, inf64, nan64, 0x01111) 1745 cmpOpTest(t, "==", eq64_ssa, eqbr64_ssa, eq32_ssa, eqbr32_ssa, zero64, one64, inf64, nan64, 0x10000) 1746 cmpOpTest(t, "<=", le64_ssa, lebr64_ssa, le32_ssa, lebr32_ssa, zero64, one64, inf64, nan64, 0x11100) 1747 cmpOpTest(t, "<", lt64_ssa, ltbr64_ssa, lt32_ssa, ltbr32_ssa, zero64, one64, inf64, nan64, 0x01100) 1748 cmpOpTest(t, ">", gt64_ssa, gtbr64_ssa, gt32_ssa, gtbr32_ssa, zero64, one64, inf64, nan64, 0x00000) 1749 cmpOpTest(t, ">=", ge64_ssa, gebr64_ssa, ge32_ssa, gebr32_ssa, zero64, one64, inf64, nan64, 0x10000) 1750 1751 { 1752 lt, le, eq, ne, ge, gt := compares64_ssa(0.0, 1.0, inf64, nan64) 1753 expectUint64(t, "lt", lt, 0x0110001000000000) 1754 expectUint64(t, "le", le, 0x1110011000100000) 1755 expectUint64(t, "eq", eq, 0x1000010000100000) 1756 expectUint64(t, "ne", ne, 0x0111101111011111) 1757 expectUint64(t, "ge", ge, 0x1000110011100000) 1758 expectUint64(t, "gt", gt, 0x0000100011000000) 1759 // fmt.Printf("lt=0x%016x, le=0x%016x, eq=0x%016x, ne=0x%016x, ge=0x%016x, gt=0x%016x\n", 1760 // lt, le, eq, ne, ge, gt) 1761 } 1762 { 1763 lt, le, eq, ne, ge, gt := compares32_ssa(0.0, 1.0, float32(inf64), float32(nan64)) 1764 expectUint64(t, "lt", lt, 0x0110001000000000) 1765 expectUint64(t, "le", le, 0x1110011000100000) 1766 expectUint64(t, "eq", eq, 0x1000010000100000) 1767 expectUint64(t, "ne", ne, 0x0111101111011111) 1768 expectUint64(t, "ge", ge, 0x1000110011100000) 1769 expectUint64(t, "gt", gt, 0x0000100011000000) 1770 } 1771 1772 floatingToIntegerConversionsTest(t) 1773 complexTest128(t) 1774 complexTest64(t) 1775 }