1// Copyright 2018 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
5package math_test
6
7import (
8	. "runtime/internal/math"
9	"testing"
10)
11
12const (
13	UintptrSize = 32 << (^uintptr(0) >> 63)
14)
15
16type mulUintptrTest struct {
17	a        uintptr
18	b        uintptr
19	overflow bool
20}
21
22var mulUintptrTests = []mulUintptrTest{
23	{0, 0, false},
24	{1000, 1000, false},
25	{MaxUintptr, 0, false},
26	{MaxUintptr, 1, false},
27	{MaxUintptr / 2, 2, false},
28	{MaxUintptr / 2, 3, true},
29	{MaxUintptr, 10, true},
30	{MaxUintptr, 100, true},
31	{MaxUintptr / 100, 100, false},
32	{MaxUintptr / 1000, 1001, true},
33	{1<<(UintptrSize/2) - 1, 1<<(UintptrSize/2) - 1, false},
34	{1 << (UintptrSize / 2), 1 << (UintptrSize / 2), true},
35	{MaxUintptr >> 32, MaxUintptr >> 32, false},
36	{MaxUintptr, MaxUintptr, true},
37}
38
39func TestMulUintptr(t *testing.T) {
40	for _, test := range mulUintptrTests {
41		a, b := test.a, test.b
42		for i := 0; i < 2; i++ {
43			mul, overflow := MulUintptr(a, b)
44			if mul != a*b || overflow != test.overflow {
45				t.Errorf("MulUintptr(%v, %v) = %v, %v want %v, %v",
46					a, b, mul, overflow, a*b, test.overflow)
47			}
48			a, b = b, a
49		}
50	}
51}
52
53var SinkUintptr uintptr
54var SinkBool bool
55
56var x, y uintptr
57
58func BenchmarkMulUintptr(b *testing.B) {
59	x, y = 1, 2
60	b.Run("small", func(b *testing.B) {
61		for i := 0; i < b.N; i++ {
62			var overflow bool
63			SinkUintptr, overflow = MulUintptr(x, y)
64			if overflow {
65				SinkUintptr = 0
66			}
67		}
68	})
69	x, y = MaxUintptr, MaxUintptr-1
70	b.Run("large", func(b *testing.B) {
71		for i := 0; i < b.N; i++ {
72			var overflow bool
73			SinkUintptr, overflow = MulUintptr(x, y)
74			if overflow {
75				SinkUintptr = 0
76			}
77		}
78	})
79}
80