]> Cypherpunks.ru repositories - gostls13.git/blob - test/rotate.go
test: expand run.go's errorcheck, make clear which bugs run
[gostls13.git] / test / rotate.go
1 // $G $D/$F.go && $L $F.$A &&
2 // ./$A.out >tmp.go && $G tmp.go && $L -o $A.out1 tmp.$A && ./$A.out1
3 // rm -f tmp.go $A.out1
4
5 // NOTE: This test is not run by 'run.go' and so not run by all.bash.
6 // To run this test you must use the ./run shell script.
7
8 // Copyright 2012 The Go Authors.  All rights reserved.
9 // Use of this source code is governed by a BSD-style
10 // license that can be found in the LICENSE file.
11
12 // Generate test of shift and rotate by constants.
13 // The output is compiled and run.
14 //
15 // The output takes around a gigabyte of memory to compile, link, and run
16 // but it is only done during ./run, not in normal builds using run.go.
17
18 package main
19
20 import (
21         "bufio"
22         "flag"
23         "fmt"
24         "os"
25         "strings"
26 )
27
28 func main() {
29         flag.Parse()
30
31         b := bufio.NewWriter(os.Stdout)
32         defer b.Flush()
33
34         fmt.Fprintf(b, "%s\n", prolog)
35
36         for logBits := uint(3); logBits <= 6; logBits++ {
37                 typ := fmt.Sprintf("int%d", 1<<logBits)
38                 fmt.Fprint(b, strings.Replace(checkFunc, "XXX", typ, -1))
39                 fmt.Fprint(b, strings.Replace(checkFunc, "XXX", "u"+typ, -1))
40                 for mode := 0; mode < 1<<2; mode++ {
41                         gentest(b, 1<<logBits, mode&1 != 0, mode&2 != 0)
42                 }
43         }
44 }
45
46 const prolog = `
47
48 package main
49
50 import (
51         "fmt"
52         "os"
53 )
54
55 var (
56         i8 int8 = 0x12
57         i16 int16 = 0x1234
58         i32 int32 = 0x12345678
59         i64 int64 = 0x123456789abcdef0
60         ui8 uint8 = 0x12
61         ui16 uint16 = 0x1234
62         ui32 uint32 = 0x12345678
63         ui64 uint64 = 0x123456789abcdef0
64
65         ni8 = ^i8
66         ni16 = ^i16
67         ni32 = ^i32
68         ni64 = ^i64
69         nui8 = ^ui8
70         nui16 = ^ui16
71         nui32 = ^ui32
72         nui64 = ^ui64
73 )
74
75 var nfail = 0
76
77 func main() {
78         if nfail > 0 {
79                 fmt.Printf("BUG\n")
80         }
81 }
82
83 `
84
85 const checkFunc = `
86 func check_XXX(desc string, have, want XXX) {
87         if have != want {
88                 nfail++
89                 fmt.Printf("%s = %T(%#x), want %T(%#x)\n", desc, have, have, want, want)
90                 if nfail >= 100 {
91                         fmt.Printf("BUG: stopping after 100 failures\n")
92                         os.Exit(0)
93                 }
94         }
95 }
96 `
97
98 var (
99         uop = [2]func(x, y uint64) uint64{
100                 func(x, y uint64) uint64 {
101                         return x | y
102                 },
103                 func(x, y uint64) uint64 {
104                         return x ^ y
105                 },
106         }
107         iop = [2]func(x, y int64) int64{
108                 func(x, y int64) int64 {
109                         return x | y
110                 },
111                 func(x, y int64) int64 {
112                         return x ^ y
113                 },
114         }
115         cop = [2]byte{'|', '^'}
116 )
117
118 func gentest(b *bufio.Writer, bits uint, unsigned, inverted bool) {
119         fmt.Fprintf(b, "func init() {\n")
120         defer fmt.Fprintf(b, "}\n")
121         n := 0
122
123         // Generate tests for left/right and right/left.
124         for l := uint(0); l <= bits; l++ {
125                 for r := uint(0); r <= bits; r++ {
126                         for o, op := range cop {
127                                 typ := fmt.Sprintf("int%d", bits)
128                                 v := fmt.Sprintf("i%d", bits)
129                                 if unsigned {
130                                         typ = "u" + typ
131                                         v = "u" + v
132                                 }
133                                 v0 := int64(0x123456789abcdef0)
134                                 if inverted {
135                                         v = "n" + v
136                                         v0 = ^v0
137                                 }
138                                 expr1 := fmt.Sprintf("%s<<%d %c %s>>%d", v, l, op, v, r)
139                                 expr2 := fmt.Sprintf("%s>>%d %c %s<<%d", v, r, op, v, l)
140
141                                 var result string
142                                 if unsigned {
143                                         v := uint64(v0) >> (64 - bits)
144                                         v = uop[o](v<<l, v>>r)
145                                         v <<= 64 - bits
146                                         v >>= 64 - bits
147                                         result = fmt.Sprintf("%#x", v)
148                                 } else {
149                                         v := int64(v0) >> (64 - bits)
150                                         v = iop[o](v<<l, v>>r)
151                                         v <<= 64 - bits
152                                         v >>= 64 - bits
153                                         result = fmt.Sprintf("%#x", v)
154                                 }
155
156                                 fmt.Fprintf(b, "\tcheck_%s(%q, %s, %s(%s))\n", typ, expr1, expr1, typ, result)
157                                 fmt.Fprintf(b, "\tcheck_%s(%q, %s, %s(%s))\n", typ, expr2, expr2, typ, result)
158
159                                 // Chop test into multiple functions so that there's not one
160                                 // enormous function to compile/link.
161                                 // All the functions are named init so we don't have to do
162                                 // anything special to call them.  ☺
163                                 if n++; n >= 50 {
164                                         fmt.Fprintf(b, "}\n")
165                                         fmt.Fprintf(b, "func init() {\n")
166                                         n = 0
167                                 }
168                         }
169                 }
170         }
171 }