Home | History | Annotate | Download | only in test
      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 }
    167