mirror of
https://github.com/golang/go
synced 2024-11-21 12:34:38 -07:00
7ab62b0bac
It is not necessary for the test to be effective and uses a lot of resources in the compiler. Memory usage is halved and compilation around 8x faster. R=golang-dev, r, rsc, r CC=golang-dev https://golang.org/cl/6290044
169 lines
3.4 KiB
Go
169 lines
3.4 KiB
Go
// $G $D/$F.go && $L $F.$A &&
|
|
// ./$A.out >tmp.go && $G tmp.go && $L -o $A.out1 tmp.$A && ./$A.out1
|
|
// rm -f tmp.go $A.out1
|
|
|
|
// Copyright 2012 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// Generate test of shift and rotate by constants.
|
|
// The output is compiled and run.
|
|
//
|
|
// The output takes around a gigabyte of memory to compile, link, and run
|
|
// but it is only done during ./run, not in normal builds using run.go.
|
|
|
|
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
|
|
b := bufio.NewWriter(os.Stdout)
|
|
defer b.Flush()
|
|
|
|
fmt.Fprintf(b, "%s\n", prolog)
|
|
|
|
for logBits := uint(3); logBits <= 6; logBits++ {
|
|
typ := fmt.Sprintf("int%d", 1<<logBits)
|
|
fmt.Fprint(b, strings.Replace(checkFunc, "XXX", typ, -1))
|
|
fmt.Fprint(b, strings.Replace(checkFunc, "XXX", "u"+typ, -1))
|
|
for mode := 0; mode < 1<<2; mode++ {
|
|
gentest(b, 1<<logBits, mode&1 != 0, mode&2 != 0)
|
|
}
|
|
}
|
|
}
|
|
|
|
const prolog = `
|
|
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
)
|
|
|
|
var (
|
|
i8 int8 = 0x12
|
|
i16 int16 = 0x1234
|
|
i32 int32 = 0x12345678
|
|
i64 int64 = 0x123456789abcdef0
|
|
ui8 uint8 = 0x12
|
|
ui16 uint16 = 0x1234
|
|
ui32 uint32 = 0x12345678
|
|
ui64 uint64 = 0x123456789abcdef0
|
|
|
|
ni8 = ^i8
|
|
ni16 = ^i16
|
|
ni32 = ^i32
|
|
ni64 = ^i64
|
|
nui8 = ^ui8
|
|
nui16 = ^ui16
|
|
nui32 = ^ui32
|
|
nui64 = ^ui64
|
|
)
|
|
|
|
var nfail = 0
|
|
|
|
func main() {
|
|
if nfail > 0 {
|
|
fmt.Printf("BUG\n")
|
|
}
|
|
}
|
|
|
|
`
|
|
|
|
const checkFunc = `
|
|
func check_XXX(desc string, have, want XXX) {
|
|
if have != want {
|
|
nfail++
|
|
fmt.Printf("%s = %T(%#x), want %T(%#x)\n", desc, have, have, want, want)
|
|
if nfail >= 100 {
|
|
fmt.Printf("BUG: stopping after 100 failures\n")
|
|
os.Exit(0)
|
|
}
|
|
}
|
|
}
|
|
`
|
|
|
|
var (
|
|
uop = [2]func(x, y uint64) uint64{
|
|
func(x, y uint64) uint64 {
|
|
return x | y
|
|
},
|
|
func(x, y uint64) uint64 {
|
|
return x ^ y
|
|
},
|
|
}
|
|
iop = [2]func(x, y int64) int64{
|
|
func(x, y int64) int64 {
|
|
return x | y
|
|
},
|
|
func(x, y int64) int64 {
|
|
return x ^ y
|
|
},
|
|
}
|
|
cop = [2]byte{'|', '^'}
|
|
)
|
|
|
|
func gentest(b *bufio.Writer, bits uint, unsigned, inverted bool) {
|
|
fmt.Fprintf(b, "func init() {\n")
|
|
defer fmt.Fprintf(b, "}\n")
|
|
n := 0
|
|
|
|
// Generate tests for left/right and right/left.
|
|
for l := uint(0); l <= bits; l++ {
|
|
for r := uint(0); r <= bits; r++ {
|
|
for o, op := range cop {
|
|
typ := fmt.Sprintf("int%d", bits)
|
|
v := fmt.Sprintf("i%d", bits)
|
|
if unsigned {
|
|
typ = "u" + typ
|
|
v = "u" + v
|
|
}
|
|
v0 := int64(0x123456789abcdef0)
|
|
if inverted {
|
|
v = "n" + v
|
|
v0 = ^v0
|
|
}
|
|
expr1 := fmt.Sprintf("%s<<%d %c %s>>%d", v, l, op, v, r)
|
|
expr2 := fmt.Sprintf("%s>>%d %c %s<<%d", v, r, op, v, l)
|
|
|
|
var result string
|
|
if unsigned {
|
|
v := uint64(v0) >> (64 - bits)
|
|
v = uop[o](v<<l, v>>r)
|
|
v <<= 64 - bits
|
|
v >>= 64 - bits
|
|
result = fmt.Sprintf("%#x", v)
|
|
} else {
|
|
v := int64(v0) >> (64 - bits)
|
|
v = iop[o](v<<l, v>>r)
|
|
v <<= 64 - bits
|
|
v >>= 64 - bits
|
|
result = fmt.Sprintf("%#x", v)
|
|
}
|
|
|
|
fmt.Fprintf(b, "\tcheck_%s(%q, %s, %s(%s))\n", typ, expr1, expr1, typ, result)
|
|
fmt.Fprintf(b, "\tcheck_%s(%q, %s, %s(%s))\n", typ, expr2, expr2, typ, result)
|
|
|
|
// Chop test into multiple functions so that there's not one
|
|
// enormous function to compile/link.
|
|
// All the functions are named init so we don't have to do
|
|
// anything special to call them. ☺
|
|
if n++; n >= 50 {
|
|
fmt.Fprintf(b, "}\n")
|
|
fmt.Fprintf(b, "func init() {\n")
|
|
n = 0
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|