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