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