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  }