]> Cypherpunks.ru repositories - gostls13.git/blob - test/fixedbugs/issue9604b.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / test / fixedbugs / issue9604b.go
1 // runoutput
2
3 // Copyright 2015 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
6
7 // terribly slow on wasm
8 //go:build !wasm
9
10 package main
11
12 import (
13         "fmt"
14         "math/big"
15         "unsafe"
16 )
17
18 var one = big.NewInt(1)
19
20 type _type struct {
21         name   string
22         bits   uint
23         signed bool
24 }
25
26 // testvalues returns a list of all test values for this type.
27 func (t *_type) testvalues() []*big.Int {
28         var a []*big.Int
29
30         a = append(a, big.NewInt(0))
31         a = append(a, big.NewInt(1))
32         a = append(a, big.NewInt(2))
33         if t.signed {
34                 a = append(a, big.NewInt(-1))
35                 a = append(a, big.NewInt(-2))
36                 r := big.NewInt(1)
37                 a = append(a, r.Lsh(r, t.bits-1).Sub(r, big.NewInt(1)))
38                 r = big.NewInt(1)
39                 a = append(a, r.Lsh(r, t.bits-1).Sub(r, big.NewInt(2)))
40                 r = big.NewInt(1)
41                 a = append(a, r.Lsh(r, t.bits-1).Neg(r))
42                 r = big.NewInt(1)
43                 a = append(a, r.Lsh(r, t.bits-1).Neg(r).Add(r, big.NewInt(1)))
44         } else {
45                 r := big.NewInt(1)
46                 a = append(a, r.Lsh(r, t.bits).Sub(r, big.NewInt(1)))
47                 r = big.NewInt(1)
48                 a = append(a, r.Lsh(r, t.bits).Sub(r, big.NewInt(2)))
49         }
50         return a
51 }
52
53 // trunc truncates a value to the range of the given type.
54 func (t *_type) trunc(x *big.Int) *big.Int {
55         r := new(big.Int)
56         m := new(big.Int)
57         m.Lsh(one, t.bits)
58         m.Sub(m, one)
59         r.And(x, m)
60         if t.signed && r.Bit(int(t.bits)-1) == 1 {
61                 m.Neg(one)
62                 m.Lsh(m, t.bits)
63                 r.Or(r, m)
64         }
65         return r
66 }
67
68 var types = []_type{
69         _type{"byte", 8, false},
70         _type{"int8", 8, true},
71         _type{"uint8", 8, false},
72         _type{"rune", 32, true},
73         _type{"int16", 16, true},
74         _type{"uint16", 16, false},
75         _type{"int32", 32, true},
76         _type{"uint32", 32, false},
77         _type{"int64", 64, true},
78         _type{"uint64", 64, false},
79         _type{"int", 8 * uint(unsafe.Sizeof(int(0))), true},
80         _type{"uint", 8 * uint(unsafe.Sizeof(uint(0))), false},
81         _type{"uintptr", 8 * uint(unsafe.Sizeof((*byte)(nil))), false},
82 }
83
84 type binop struct {
85         name string
86         eval func(x, y *big.Int) *big.Int
87 }
88
89 var binops = []binop{
90         binop{"+", func(x, y *big.Int) *big.Int { return new(big.Int).Add(x, y) }},
91         binop{"-", func(x, y *big.Int) *big.Int { return new(big.Int).Sub(x, y) }},
92         binop{"*", func(x, y *big.Int) *big.Int { return new(big.Int).Mul(x, y) }},
93         binop{"/", func(x, y *big.Int) *big.Int { return new(big.Int).Quo(x, y) }},
94         binop{"%", func(x, y *big.Int) *big.Int { return new(big.Int).Rem(x, y) }},
95         binop{"&", func(x, y *big.Int) *big.Int { return new(big.Int).And(x, y) }},
96         binop{"|", func(x, y *big.Int) *big.Int { return new(big.Int).Or(x, y) }},
97         binop{"^", func(x, y *big.Int) *big.Int { return new(big.Int).Xor(x, y) }},
98         binop{"&^", func(x, y *big.Int) *big.Int { return new(big.Int).AndNot(x, y) }},
99 }
100
101 type unop struct {
102         name string
103         eval func(x *big.Int) *big.Int
104 }
105
106 var unops = []unop{
107         unop{"+", func(x *big.Int) *big.Int { return new(big.Int).Set(x) }},
108         unop{"-", func(x *big.Int) *big.Int { return new(big.Int).Neg(x) }},
109         unop{"^", func(x *big.Int) *big.Int { return new(big.Int).Not(x) }},
110 }
111
112 type shiftop struct {
113         name string
114         eval func(x *big.Int, i uint) *big.Int
115 }
116
117 var shiftops = []shiftop{
118         shiftop{"<<", func(x *big.Int, i uint) *big.Int { return new(big.Int).Lsh(x, i) }},
119         shiftop{">>", func(x *big.Int, i uint) *big.Int { return new(big.Int).Rsh(x, i) }},
120 }
121
122 // valname returns the name of n as can be used as part of a variable name.
123 func valname(n *big.Int) string {
124         s := fmt.Sprintf("%d", n)
125         if s[0] == '-' {
126                 s = "neg" + s[1:]
127         }
128         return s
129 }
130
131 func main() {
132         fmt.Println("package main")
133
134         // We make variables to hold all the different values we'd like to use.
135         // We use global variables to prevent any constant folding.
136         for _, t := range types {
137                 for _, n := range t.testvalues() {
138                         fmt.Printf("var %s_%s %s = %d\n", t.name, valname(n), t.name, n)
139                 }
140         }
141
142         fmt.Println("func main() {")
143
144         for _, t := range types {
145                 // test binary ops
146                 for _, op := range binops {
147                         for _, x := range t.testvalues() {
148                                 for _, y := range t.testvalues() {
149                                         if (op.name == "/" || op.name == "%") && y.Sign() == 0 {
150                                                 continue
151                                         }
152                                         r := t.trunc(op.eval(x, y))
153                                         eqn := fmt.Sprintf("%s_%s %s %s_%s != %d", t.name, valname(x), op.name, t.name, valname(y), r)
154                                         fmt.Printf("\tif %s { println(\"bad: %s\") }\n", eqn, eqn)
155                                 }
156                         }
157                 }
158                 // test unary ops
159                 for _, op := range unops {
160                         for _, x := range t.testvalues() {
161                                 r := t.trunc(op.eval(x))
162                                 eqn := fmt.Sprintf("%s %s_%s != %d", op.name, t.name, valname(x), r)
163                                 fmt.Printf("\tif %s { println(\"bad: %s\") }\n", eqn, eqn)
164                         }
165                 }
166                 // test shifts
167                 for _, op := range shiftops {
168                         for _, x := range t.testvalues() {
169
170                                 for _, i := range []uint{0, 1, t.bits - 2, t.bits - 1, t.bits, t.bits + 1} {
171                                         r := t.trunc(op.eval(x, i))
172                                         eqn := fmt.Sprintf("%s_%s %s %d != %d", t.name, valname(x), op.name, i, r)
173                                         fmt.Printf("\tif %s { println(\"bad: %s\") }\n", eqn, eqn)
174                                 }
175                         }
176                 }
177         }
178
179         fmt.Println("}")
180 }