| 
									
										
										
										
											2013-01-11 22:42:55 +01:00
										 |  |  | // skip | 
					
						
							| 
									
										
										
										
											2012-05-24 17:20:07 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-11 22:42:55 +01:00
										 |  |  | // NOTE: the actual tests to run are rotate[0123].go | 
					
						
							| 
									
										
										
										
											2012-09-23 13:16:14 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-10 14:32:26 -07:00
										 |  |  | // Copyright 2012 The Go Authors. All rights reserved. | 
					
						
							| 
									
										
										
										
											2012-05-24 17:20:07 -04:00
										 |  |  | // 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. | 
					
						
							|  |  |  | // | 
					
						
							| 
									
										
										
										
											2013-01-11 22:42:55 +01:00
										 |  |  | // The integer type depends on the value of mode (rotate direction, | 
					
						
							|  |  |  | // signedness). | 
					
						
							| 
									
										
										
										
											2012-05-24 17:20:07 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | package main | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"bufio" | 
					
						
							|  |  |  | 	"flag" | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"os" | 
					
						
							| 
									
										
										
										
											2012-06-04 23:31:31 +02:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2012-05-24 17:20:07 -04:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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++ { | 
					
						
							| 
									
										
										
										
											2012-06-04 23:31:31 +02:00
										 |  |  | 		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)) | 
					
						
							| 
									
										
										
										
											2013-01-11 22:42:55 +01:00
										 |  |  | 		gentest(b, 1<<logBits, mode&1 != 0, mode&2 != 0) | 
					
						
							| 
									
										
										
										
											2012-05-24 17:20:07 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-04 23:31:31 +02:00
										 |  |  | func main() { | 
					
						
							|  |  |  | 	if nfail > 0 { | 
					
						
							|  |  |  | 		fmt.Printf("BUG\n") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const checkFunc = ` | 
					
						
							|  |  |  | func check_XXX(desc string, have, want XXX) { | 
					
						
							| 
									
										
										
										
											2012-05-24 17:20:07 -04:00
										 |  |  | 	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) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-04 20:53:32 +10:00
										 |  |  | 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{'|', '^'} | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-24 17:20:07 -04:00
										 |  |  | 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++ { | 
					
						
							| 
									
										
										
										
											2012-06-04 20:53:32 +10:00
										 |  |  | 			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) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-04 23:31:31 +02:00
										 |  |  | 				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) | 
					
						
							| 
									
										
										
										
											2012-06-04 20:53:32 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				// 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 | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-05-24 17:20:07 -04:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |