github.com/karrick/go@v0.0.0-20170817181416-d5b0ec858b37/test/rotate.go (about) 1 // skip 2 3 // NOTE: the actual tests to run are rotate[0123].go 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 integer type depends on the value of mode (rotate direction, 13 // signedness). 14 15 package main 16 17 import ( 18 "bufio" 19 "flag" 20 "fmt" 21 "os" 22 "strings" 23 ) 24 25 func main() { 26 flag.Parse() 27 28 b := bufio.NewWriter(os.Stdout) 29 defer b.Flush() 30 31 fmt.Fprintf(b, "%s\n", prolog) 32 33 for logBits := uint(3); logBits <= 6; logBits++ { 34 typ := fmt.Sprintf("int%d", 1<<logBits) 35 fmt.Fprint(b, strings.Replace(checkFunc, "XXX", typ, -1)) 36 fmt.Fprint(b, strings.Replace(checkFunc, "XXX", "u"+typ, -1)) 37 gentest(b, 1<<logBits, mode&1 != 0, mode&2 != 0) 38 } 39 } 40 41 const prolog = ` 42 43 package main 44 45 import ( 46 "fmt" 47 "os" 48 ) 49 50 var ( 51 i8 int8 = 0x12 52 i16 int16 = 0x1234 53 i32 int32 = 0x12345678 54 i64 int64 = 0x123456789abcdef0 55 ui8 uint8 = 0x12 56 ui16 uint16 = 0x1234 57 ui32 uint32 = 0x12345678 58 ui64 uint64 = 0x123456789abcdef0 59 60 ni8 = ^i8 61 ni16 = ^i16 62 ni32 = ^i32 63 ni64 = ^i64 64 nui8 = ^ui8 65 nui16 = ^ui16 66 nui32 = ^ui32 67 nui64 = ^ui64 68 ) 69 70 var nfail = 0 71 72 func main() { 73 if nfail > 0 { 74 fmt.Printf("BUG\n") 75 } 76 } 77 78 ` 79 80 const checkFunc = ` 81 func check_XXX(desc string, have, want XXX) { 82 if have != want { 83 nfail++ 84 fmt.Printf("%s = %T(%#x), want %T(%#x)\n", desc, have, have, want, want) 85 if nfail >= 100 { 86 fmt.Printf("BUG: stopping after 100 failures\n") 87 os.Exit(0) 88 } 89 } 90 } 91 ` 92 93 var ( 94 uop = [2]func(x, y uint64) uint64{ 95 func(x, y uint64) uint64 { 96 return x | y 97 }, 98 func(x, y uint64) uint64 { 99 return x ^ y 100 }, 101 } 102 iop = [2]func(x, y int64) int64{ 103 func(x, y int64) int64 { 104 return x | y 105 }, 106 func(x, y int64) int64 { 107 return x ^ y 108 }, 109 } 110 cop = [2]byte{'|', '^'} 111 ) 112 113 func gentest(b *bufio.Writer, bits uint, unsigned, inverted bool) { 114 fmt.Fprintf(b, "func init() {\n") 115 defer fmt.Fprintf(b, "}\n") 116 n := 0 117 118 // Generate tests for left/right and right/left. 119 for l := uint(0); l <= bits; l++ { 120 for r := uint(0); r <= bits; r++ { 121 for o, op := range cop { 122 typ := fmt.Sprintf("int%d", bits) 123 v := fmt.Sprintf("i%d", bits) 124 if unsigned { 125 typ = "u" + typ 126 v = "u" + v 127 } 128 v0 := int64(0x123456789abcdef0) 129 if inverted { 130 v = "n" + v 131 v0 = ^v0 132 } 133 expr1 := fmt.Sprintf("%s<<%d %c %s>>%d", v, l, op, v, r) 134 expr2 := fmt.Sprintf("%s>>%d %c %s<<%d", v, r, op, v, l) 135 136 var result string 137 if unsigned { 138 v := uint64(v0) >> (64 - bits) 139 v = uop[o](v<<l, v>>r) 140 v <<= 64 - bits 141 v >>= 64 - bits 142 result = fmt.Sprintf("%#x", v) 143 } else { 144 v := int64(v0) >> (64 - bits) 145 v = iop[o](v<<l, v>>r) 146 v <<= 64 - bits 147 v >>= 64 - bits 148 result = fmt.Sprintf("%#x", v) 149 } 150 151 fmt.Fprintf(b, "\tcheck_%s(%q, %s, %s(%s))\n", typ, expr1, expr1, typ, result) 152 fmt.Fprintf(b, "\tcheck_%s(%q, %s, %s(%s))\n", typ, expr2, expr2, typ, result) 153 154 // Chop test into multiple functions so that there's not one 155 // enormous function to compile/link. 156 // All the functions are named init so we don't have to do 157 // anything special to call them. ☺ 158 if n++; n >= 50 { 159 fmt.Fprintf(b, "}\n") 160 fmt.Fprintf(b, "func init() {\n") 161 n = 0 162 } 163 } 164 } 165 } 166 }