Home | History | Annotate | Download | only in test
      1 // runoutput
      2 
      3 // Copyright 2009 The Go Authors. All rights reserved.
      4 // Use of this source code is governed by a BSD-style
      5 // license that can be found in the LICENSE file.
      6 
      7 // Generate test of 64-bit arithmetic.
      8 // Most synthesized routines have different cases for
      9 // constants vs variables and even the generated code has
     10 // different cases for large and small constants,
     11 // so try a good range of inputs.
     12 
     13 package main
     14 
     15 import (
     16 	"bufio"
     17 	"fmt"
     18 	"os"
     19 )
     20 
     21 var bout *bufio.Writer
     22 
     23 // 64-bit math without using 64-bit numbers,
     24 // so that we can generate the test program even
     25 // if the compiler has buggy or missing 64-bit support.
     26 
     27 type Uint64 struct {
     28 	hi	uint32
     29 	lo	uint32
     30 }
     31 
     32 type Int64 struct {
     33 	hi	int32
     34 	lo	uint32
     35 }
     36 
     37 func (a Uint64) Int64() (c Int64) {
     38 	c.hi = int32(a.hi)
     39 	c.lo = a.lo
     40 	return
     41 }
     42 
     43 func (a Uint64) Cmp(b Uint64) int {
     44 	switch {
     45 	case a.hi < b.hi:
     46 		return -1
     47 	case a.hi > b.hi:
     48 		return 1
     49 	case a.lo < b.lo:
     50 		return -1
     51 	case a.lo > b.lo:
     52 		return 1
     53 	}
     54 	return 0
     55 }
     56 
     57 func (a Uint64) LeftShift(b uint) (c Uint64) {
     58 	switch {
     59 	case b >= 64:
     60 		c.hi = 0
     61 		c.lo = 0
     62 	case b >= 32:
     63 		c.hi = a.lo << (b - 32)
     64 		c.lo = 0
     65 	default:
     66 		c.hi = a.hi<<b | a.lo>>(32-b)
     67 		c.lo = a.lo << b
     68 	}
     69 	return
     70 }
     71 
     72 func (a Uint64) RightShift(b uint) (c Uint64) {
     73 	switch {
     74 	case b >= 64:
     75 		c.hi = 0
     76 		c.lo = a.hi
     77 	case b >= 32:
     78 		c.hi = 0
     79 		c.lo = a.hi >> (b - 32)
     80 	default:
     81 		c.hi = a.hi >> b
     82 		c.lo = a.hi<<(32-b) | a.lo>>b
     83 	}
     84 	return
     85 }
     86 
     87 func (a Uint64) LeftShift64(b Uint64) (c Uint64) {
     88 	if b.hi != 0 || b.lo >= 64 {
     89 		return
     90 	}
     91 	return a.LeftShift(uint(b.lo))
     92 }
     93 
     94 func (a Uint64) RightShift64(b Uint64) (c Uint64) {
     95 	if b.hi != 0 || b.lo >= 64 {
     96 		return
     97 	}
     98 	return a.RightShift(uint(b.lo))
     99 }
    100 
    101 func (a Uint64) Plus(b Uint64) (c Uint64) {
    102 	var carry uint32
    103 	if c.lo = a.lo + b.lo; c.lo < a.lo {
    104 		carry = 1
    105 	}
    106 	c.hi = a.hi + b.hi + carry
    107 	return
    108 }
    109 
    110 func (a Uint64) Minus(b Uint64) (c Uint64) {
    111 	var borrow uint32
    112 	if c.lo = a.lo - b.lo; c.lo > a.lo {
    113 		borrow = 1
    114 	}
    115 	c.hi = a.hi - b.hi - borrow
    116 	return
    117 }
    118 
    119 func (a Uint64) Neg() (c Uint64) {
    120 	var zero Uint64
    121 	return zero.Minus(a)
    122 }
    123 
    124 func (a Uint64) Com() (c Uint64) {
    125 	c.hi = ^a.hi
    126 	c.lo = ^a.lo
    127 	return
    128 }
    129 
    130 func (a Uint64) Len() int {
    131 	switch {
    132 	case a.hi != 0:
    133 		for i := 31; i >= 0; i-- {
    134 			if a.hi&(1<<uint(i)) != 0 {
    135 				return i + 1 + 32
    136 			}
    137 		}
    138 	case a.lo != 0:
    139 		for i := 31; i >= 0; i-- {
    140 			if a.lo&(1<<uint(i)) != 0 {
    141 				return i + 1
    142 			}
    143 		}
    144 	}
    145 	return 0
    146 }
    147 
    148 func (a Uint64) HasBit(b uint) bool {
    149 	switch {
    150 	case b >= 64:
    151 		return false
    152 	case b >= 32:
    153 		return a.hi&(1<<(b-32)) != 0
    154 	}
    155 	return a.lo&(1<<b) != 0
    156 }
    157 
    158 func (a Uint64) Times(b Uint64) (c Uint64) {
    159 	for i := uint(0); i < 64; i++ {
    160 		if b.HasBit(i) {
    161 			c = c.Plus(a.LeftShift(i))
    162 		}
    163 	}
    164 	return
    165 }
    166 
    167 func (a Uint64) DivMod(b Uint64) (quo, rem Uint64) {
    168 	n := a.Len() - b.Len()
    169 	if n >= 0 {
    170 		b = b.LeftShift(uint(n))
    171 		for i := 0; i <= n; i++ {
    172 			quo = quo.LeftShift(1)
    173 			if b.Cmp(a) <= 0 {	// b <= a
    174 				quo.lo |= 1
    175 				a = a.Minus(b)
    176 			}
    177 			b = b.RightShift(1)
    178 		}
    179 	}
    180 	rem = a
    181 	return
    182 }
    183 
    184 func (a Uint64) And(b Uint64) (c Uint64) {
    185 	c.hi = a.hi & b.hi
    186 	c.lo = a.lo & b.lo
    187 	return
    188 }
    189 
    190 func (a Uint64) AndNot(b Uint64) (c Uint64) {
    191 	c.hi = a.hi &^ b.hi
    192 	c.lo = a.lo &^ b.lo
    193 	return
    194 }
    195 
    196 func (a Uint64) Or(b Uint64) (c Uint64) {
    197 	c.hi = a.hi | b.hi
    198 	c.lo = a.lo | b.lo
    199 	return
    200 }
    201 
    202 func (a Uint64) Xor(b Uint64) (c Uint64) {
    203 	c.hi = a.hi ^ b.hi
    204 	c.lo = a.lo ^ b.lo
    205 	return
    206 }
    207 
    208 func (a Uint64) String() string	{ return fmt.Sprintf("%#x%08x", a.hi, a.lo) }
    209 
    210 func (a Int64) Uint64() (c Uint64) {
    211 	c.hi = uint32(a.hi)
    212 	c.lo = a.lo
    213 	return
    214 }
    215 
    216 func (a Int64) Cmp(b Int64) int {
    217 	// Same body as Uint64.Cmp,
    218 	// but behaves differently
    219 	// because hi is uint32 not int32.
    220 	switch {
    221 	case a.hi < b.hi:
    222 		return -1
    223 	case a.hi > b.hi:
    224 		return 1
    225 	case a.lo < b.lo:
    226 		return -1
    227 	case a.lo > b.lo:
    228 		return 1
    229 	}
    230 	return 0
    231 }
    232 
    233 func (a Int64) LeftShift(b uint) (c Int64)	{ return a.Uint64().LeftShift(b).Int64() }
    234 
    235 func (a Int64) RightShift(b uint) (c Int64) {
    236 	switch {
    237 	case b >= 64:
    238 		c.hi = a.hi >> 31	// sign extend
    239 		c.lo = uint32(c.hi)
    240 	case b >= 32:
    241 		c.hi = a.hi >> 31	// sign extend
    242 		c.lo = uint32(a.hi >> (b - 32))
    243 	default:
    244 		c.hi = a.hi >> b
    245 		c.lo = uint32(a.hi<<(32-b)) | a.lo>>b
    246 	}
    247 	return
    248 }
    249 
    250 func (a Int64) LeftShift64(b Uint64) (c Int64) {
    251 	if b.hi != 0 || b.lo >= 64 {
    252 		return
    253 	}
    254 	return a.LeftShift(uint(b.lo))
    255 }
    256 
    257 func (a Int64) RightShift64(b Uint64) (c Int64) {
    258 	if b.hi != 0 || b.lo >= 64 {
    259 		return a.RightShift(64)
    260 	}
    261 	return a.RightShift(uint(b.lo))
    262 }
    263 
    264 func (a Int64) Plus(b Int64) (c Int64)	{ return a.Uint64().Plus(b.Uint64()).Int64() }
    265 
    266 func (a Int64) Minus(b Int64) (c Int64)	{ return a.Uint64().Minus(b.Uint64()).Int64() }
    267 
    268 func (a Int64) Neg() (c Int64)	{ return a.Uint64().Neg().Int64() }
    269 
    270 func (a Int64) Com() (c Int64)	{ return a.Uint64().Com().Int64() }
    271 
    272 func (a Int64) Times(b Int64) (c Int64)	{ return a.Uint64().Times(b.Uint64()).Int64() }
    273 
    274 func (a Int64) DivMod(b Int64) (quo Int64, rem Int64) {
    275 	var zero Int64
    276 
    277 	quoSign := +1
    278 	remSign := +1
    279 	if a.Cmp(zero) < 0 {
    280 		quoSign = -1
    281 		remSign = -1
    282 		a = a.Neg()
    283 	}
    284 	if b.Cmp(zero) < 0 {
    285 		quoSign = -quoSign
    286 		b = b.Neg()
    287 	}
    288 
    289 	q, r := a.Uint64().DivMod(b.Uint64())
    290 	quo = q.Int64()
    291 	rem = r.Int64()
    292 
    293 	if quoSign < 0 {
    294 		quo = quo.Neg()
    295 	}
    296 	if remSign < 0 {
    297 		rem = rem.Neg()
    298 	}
    299 	return
    300 }
    301 
    302 func (a Int64) And(b Int64) (c Int64)	{ return a.Uint64().And(b.Uint64()).Int64() }
    303 
    304 func (a Int64) AndNot(b Int64) (c Int64)	{ return a.Uint64().AndNot(b.Uint64()).Int64() }
    305 
    306 func (a Int64) Or(b Int64) (c Int64)	{ return a.Uint64().Or(b.Uint64()).Int64() }
    307 
    308 func (a Int64) Xor(b Int64) (c Int64)	{ return a.Uint64().Xor(b.Uint64()).Int64() }
    309 
    310 func (a Int64) String() string {
    311 	if a.hi < 0 {
    312 		return fmt.Sprintf("-%s", a.Neg().Uint64())
    313 	}
    314 	return a.Uint64().String()
    315 }
    316 
    317 var int64Values = []Int64{
    318 	Int64{0, 0},
    319 	Int64{0, 1},
    320 	Int64{0, 2},
    321 	Int64{0, 3},
    322 	Int64{0, 100},
    323 	Int64{0, 10001},
    324 	Int64{0, 1<<31 - 1},
    325 	Int64{0, 1 << 31},
    326 	Int64{0, 1<<31 + 1},
    327 	Int64{0, 1<<32 - 1<<30},
    328 	Int64{0, 1<<32 - 1},
    329 	Int64{1, 0},
    330 	Int64{1, 1},
    331 	Int64{2, 0},
    332 	Int64{1<<31 - 1, 1<<32 - 10000},
    333 	Int64{1<<31 - 1, 1<<32 - 1},
    334 	Int64{0x789abcde, 0xf0123456},
    335 
    336 	Int64{-1, 1<<32 - 1},
    337 	Int64{-1, 1<<32 - 2},
    338 	Int64{-1, 1<<32 - 3},
    339 	Int64{-1, 1<<32 - 100},
    340 	Int64{-1, 1<<32 - 10001},
    341 	Int64{-1, 1<<32 - (1<<31 - 1)},
    342 	Int64{-1, 1<<32 - 1<<31},
    343 	Int64{-1, 1<<32 - (1<<31 + 1)},
    344 	Int64{-1, 1<<32 - (1<<32 - 1<<30)},
    345 	Int64{-1, 0},
    346 	Int64{-1, 1},
    347 	Int64{-2, 0},
    348 	Int64{-(1 << 31), 10000},
    349 	Int64{-(1 << 31), 1},
    350 	Int64{-(1 << 31), 0},
    351 	Int64{-0x789abcde, 0xf0123456},
    352 }
    353 
    354 var uint64Values = []Uint64{
    355 	Uint64{0, 0},
    356 	Uint64{0, 1},
    357 	Uint64{0, 2},
    358 	Uint64{0, 3},
    359 	Uint64{0, 100},
    360 	Uint64{0, 10001},
    361 	Uint64{0, 1<<31 - 1},
    362 	Uint64{0, 1 << 31},
    363 	Uint64{0, 1<<31 + 1},
    364 	Uint64{0, 1<<32 - 1<<30},
    365 	Uint64{0, 1<<32 - 1},
    366 	Uint64{1, 0},
    367 	Uint64{1, 1},
    368 	Uint64{2, 0},
    369 	Uint64{1<<31 - 1, 1<<32 - 10000},
    370 	Uint64{1<<31 - 1, 1<<32 - 1},
    371 	Uint64{1<<32 - 1<<30, 0},
    372 	Uint64{1<<32 - 1, 0},
    373 	Uint64{1<<32 - 1, 1<<32 - 100},
    374 	Uint64{1<<32 - 1, 1<<32 - 1},
    375 	Uint64{0x789abcde, 0xf0123456},
    376 	Uint64{0xfedcba98, 0x76543210},
    377 }
    378 
    379 var shiftValues = []Uint64{
    380 	Uint64{0, 0},
    381 	Uint64{0, 1},
    382 	Uint64{0, 2},
    383 	Uint64{0, 3},
    384 	Uint64{0, 15},
    385 	Uint64{0, 16},
    386 	Uint64{0, 17},
    387 	Uint64{0, 31},
    388 	Uint64{0, 32},
    389 	Uint64{0, 33},
    390 	Uint64{0, 61},
    391 	Uint64{0, 62},
    392 	Uint64{0, 63},
    393 	Uint64{0, 64},
    394 	Uint64{0, 65},
    395 	Uint64{0, 1<<32 - 1},
    396 	Uint64{1, 0},
    397 	Uint64{1, 1},
    398 	Uint64{1 << 28, 0},
    399 	Uint64{1 << 31, 0},
    400 	Uint64{1<<32 - 1, 0},
    401 	Uint64{1<<32 - 1, 1<<32 - 1},
    402 }
    403 
    404 var ntest = 0
    405 
    406 // Part 1 is tests of variable operations; generic functions
    407 // called by repetitive code.  Could make a table but not worth it.
    408 
    409 const prolog = "\n" +
    410 	"package main\n" +
    411 	"\n" +
    412 	"import \"os\"\n" +
    413 	"\n" +
    414 	"var ok = true\n" +
    415 	"\n" +
    416 	"func testInt64Unary(a, plus, xor, minus int64) {\n" +
    417 	"	if n, op, want := +a, `+`, plus; n != want { ok=false; println(`int64`, op, a, `=`, n, `should be`, want); }\n" +
    418 	"	if n, op, want := ^a, `^`, xor; n != want { ok=false; println(`int64`, op, a, `=`, n, `should be`, want); }\n" +
    419 	"	if n, op, want := -a, `-`, minus; n != want { ok=false; println(`int64`, op, a, `=`, n, `should be`, want); }\n" +
    420 	"}\n" +
    421 	"\n" +
    422 	"func testInt64Binary(a, b, add, sub, mul, div, mod, and, or, xor, andnot int64, dodiv bool) {\n" +
    423 	"	if n, op, want := a + b, `+`, add; n != want { ok=false; println(`int64`, a, op, b, `=`, n, `should be`, want); }\n" +
    424 	"	if n, op, want := a - b, `-`, sub; n != want { ok=false; println(`int64`, a, op, b, `=`, n, `should be`, want); }\n" +
    425 	"	if n, op, want := a * b, `*`, mul; n != want { ok=false; println(`int64`, a, op, b, `=`, n, `should be`, want); }\n" +
    426 	"	if dodiv {\n" +
    427 	"		if n, op, want := a / b, `/`, div; n != want { ok=false; println(`int64`, a, op, b, `=`, n, `should be`, want); }\n" +
    428 	"		if n, op, want := a % b, `%`, mod; n != want { ok=false; println(`int64`, a, op, b, `=`, n, `should be`, want); }\n" +
    429 	"	}\n" +
    430 	"	if n, op, want := a & b, `&`, and; n != want { ok=false; println(`int64`, a, op, b, `=`, n, `should be`, want); }\n" +
    431 	"	if n, op, want := a | b, `|`, or; n != want { ok=false; println(`int64`, a, op, b, `=`, n, `should be`, want); }\n" +
    432 	"	if n, op, want := a ^ b, `^`, xor; n != want { ok=false; println(`int64`, a, op, b, `=`, n, `should be`, want); }\n" +
    433 	"	if n, op, want := a &^ b, `&^`, andnot; n != want { ok=false; println(`int64`, a, op, b, `=`, n, `should be`, want); }\n" +
    434 	"}\n" +
    435 	"\n" +
    436 	"func testInt64Shift(a int64, b uint64, left, right int64) {\n" +
    437 	"	if n, op, s, want := a << b, `<<`, b, left; n != want { ok=false; println(`int64`, a, op, `uint64`, s, `=`, n, `should be`, want); }\n" +
    438 	"	if n, op, s, want := a >> b, `>>`, b, right; n != want { ok=false; println(`int64`, a, op, `uint64`, s, `=`, n, `should be`, want); }\n" +
    439 	"	if uint64(uint(b)) == b {\n" +
    440 	"		b := uint(b);\n" +
    441 	"		if n, op, s, want := a << b, `<<`, b, left; n != want { ok=false; println(`int64`, a, op, `uint`, s, `=`, n, `should be`, want); }\n" +
    442 	"		if n, op, s, want := a >> b, `>>`, b, right; n != want { ok=false; println(`int64`, a, op, `uint`, s, `=`, n, `should be`, want); }\n" +
    443 	"	}\n" +
    444 	"	if uint64(uint32(b)) == b {\n" +
    445 	"		b := uint32(b);\n" +
    446 	"		if n, op, s, want := a << b, `<<`, b, left; n != want { ok=false; println(`int64`, a, op, `uint32`, s, `=`, n, `should be`, want); }\n" +
    447 	"		if n, op, s, want := a >> b, `>>`, b, right; n != want { ok=false; println(`int64`, a, op, `uint32`, s, `=`, n, `should be`, want); }\n" +
    448 	"	}\n" +
    449 	"	if uint64(uint16(b)) == b {\n" +
    450 	"		b := uint16(b);\n" +
    451 	"		if n, op, s, want := a << b, `<<`, b, left; n != want { ok=false; println(`int64`, a, op, `uint16`, s, `=`, n, `should be`, want); }\n" +
    452 	"		if n, op, s, want := a >> b, `>>`, b, right; n != want { ok=false; println(`int64`, a, op, `uint16`, s, `=`, n, `should be`, want); }\n" +
    453 	"	}\n" +
    454 	"	if uint64(uint8(b)) == b {\n" +
    455 	"		b := uint8(b);\n" +
    456 	"		if n, op, s, want := a << b, `<<`, b, left; n != want { ok=false; println(`int64`, a, op, `uint8`, s, `=`, n, `should be`, want); }\n" +
    457 	"		if n, op, s, want := a >> b, `>>`, b, right; n != want { ok=false; println(`int64`, a, op, `uint8`, s, `=`, n, `should be`, want); }\n" +
    458 	"	}\n" +
    459 	"}\n" +
    460 	"\n" +
    461 	"func testUint64Unary(a, plus, xor, minus uint64) {\n" +
    462 	"	if n, op, want := +a, `+`, plus; n != want { ok=false; println(`uint64`, op, a, `=`, n, `should be`, want); }\n" +
    463 	"	if n, op, want := ^a, `^`, xor; n != want { ok=false; println(`uint64`, op, a, `=`, n, `should be`, want); }\n" +
    464 	"	if n, op, want := -a, `-`, minus; n != want { ok=false; println(`uint64`, op, a, `=`, n, `should be`, want); }\n" +
    465 	"}\n" +
    466 	"\n" +
    467 	"func testUint64Binary(a, b, add, sub, mul, div, mod, and, or, xor, andnot uint64, dodiv bool) {\n" +
    468 	"	if n, op, want := a + b, `+`, add; n != want { ok=false; println(`uint64`, a, op, b, `=`, n, `should be`, want); }\n" +
    469 	"	if n, op, want := a - b, `-`, sub; n != want { ok=false; println(`uint64`, a, op, b, `=`, n, `should be`, want); }\n" +
    470 	"	if n, op, want := a * b, `*`, mul; n != want { ok=false; println(`uint64`, a, op, b, `=`, n, `should be`, want); }\n" +
    471 	"	if dodiv {\n" +
    472 	"		if n, op, want := a / b, `/`, div; n != want { ok=false; println(`uint64`, a, op, b, `=`, n, `should be`, want); }\n" +
    473 	"		if n, op, want := a % b, `%`, mod; n != want { ok=false; println(`uint64`, a, op, b, `=`, n, `should be`, want); }\n" +
    474 	"	}\n" +
    475 	"	if n, op, want := a & b, `&`, and; n != want { ok=false; println(`uint64`, a, op, b, `=`, n, `should be`, want); }\n" +
    476 	"	if n, op, want := a | b, `|`, or; n != want { ok=false; println(`uint64`, a, op, b, `=`, n, `should be`, want); }\n" +
    477 	"	if n, op, want := a ^ b, `^`, xor; n != want { ok=false; println(`uint64`, a, op, b, `=`, n, `should be`, want); }\n" +
    478 	"	if n, op, want := a &^ b, `&^`, andnot; n != want { ok=false; println(`uint64`, a, op, b, `=`, n, `should be`, want); }\n" +
    479 	"}\n" +
    480 	"\n" +
    481 	"func testUint64Shift(a, b, left, right uint64) {\n" +
    482 	"	if n, op, s, want := a << b, `<<`, b, left; n != want { ok=false; println(`uint64`, a, op, `uint64`, s, `=`, n, `should be`, want); }\n" +
    483 	"	if n, op, s, want := a >> b, `>>`, b, right; n != want { ok=false; println(`uint64`, a, op, `uint64`, s, `=`, n, `should be`, want); }\n" +
    484 	"	if uint64(uint(b)) == b {\n" +
    485 	"		b := uint(b);\n" +
    486 	"		if n, op, s, want := a << b, `<<`, b, left; n != want { ok=false; println(`uint64`, a, op, `uint`, s, `=`, n, `should be`, want); }\n" +
    487 	"		if n, op, s, want := a >> b, `>>`, b, right; n != want { ok=false; println(`uint64`, a, op, `uint`, s, `=`, n, `should be`, want); }\n" +
    488 	"	}\n" +
    489 	"	if uint64(uint32(b)) == b {\n" +
    490 	"		b := uint32(b);\n" +
    491 	"		if n, op, s, want := a << b, `<<`, b, left; n != want { ok=false; println(`uint64`, a, op, `uint32`, s, `=`, n, `should be`, want); }\n" +
    492 	"		if n, op, s, want := a >> b, `>>`, b, right; n != want { ok=false; println(`uint64`, a, op, `uint32`, s, `=`, n, `should be`, want); }\n" +
    493 	"	}\n" +
    494 	"	if uint64(uint16(b)) == b {\n" +
    495 	"		b := uint16(b);\n" +
    496 	"		if n, op, s, want := a << b, `<<`, b, left; n != want { ok=false; println(`uint64`, a, op, `uint16`, s, `=`, n, `should be`, want); }\n" +
    497 	"		if n, op, s, want := a >> b, `>>`, b, right; n != want { ok=false; println(`uint64`, a, op, `uint16`, s, `=`, n, `should be`, want); }\n" +
    498 	"	}\n" +
    499 	"	if uint64(uint8(b)) == b {\n" +
    500 	"		b := uint8(b);\n" +
    501 	"		if n, op, s, want := a << b, `<<`, b, left; n != want { ok=false; println(`uint64`, a, op, `uint8`, s, `=`, n, `should be`, want); }\n" +
    502 	"		if n, op, s, want := a >> b, `>>`, b, right; n != want { ok=false; println(`uint64`, a, op, `uint8`, s, `=`, n, `should be`, want); }\n" +
    503 	"	}\n" +
    504 	"}\n" +
    505 	"\n"
    506 
    507 func varTests() {
    508 	fmt.Fprint(bout, prolog)
    509 	for _, a := range int64Values {
    510 		fmt.Fprintf(bout, "func test%v() {\n", ntest)
    511 		ntest++
    512 		fmt.Fprintf(bout, "\ttestInt64Unary(%v, %v, %v, %v);\n", a, a, a.Com(), a.Neg())
    513 		for _, b := range int64Values {
    514 			var div, mod Int64
    515 			dodiv := false
    516 			var zero Int64
    517 			if b.Cmp(zero) != 0 {	// b != 0
    518 				// Can't divide by zero but also can't divide -0x8000...000 by -1.
    519 				var bigneg = Int64{-0x80000000, 0}
    520 				var minus1 = Int64{-1, ^uint32(0)}
    521 				if a.Cmp(bigneg) != 0 || b.Cmp(minus1) != 0 {	// a != -1<<63 || b != -1
    522 					div, mod = a.DivMod(b)
    523 					dodiv = true
    524 				}
    525 			}
    526 			fmt.Fprintf(bout, "\ttestInt64Binary(%v, %v, %v, %v, %v, %v, %v, %v, %v, %v, %v, %v);\n",
    527 				a, b, a.Plus(b), a.Minus(b), a.Times(b), div, mod,
    528 				a.And(b), a.Or(b), a.Xor(b), a.AndNot(b), dodiv)
    529 		}
    530 		for _, b := range shiftValues {
    531 			fmt.Fprintf(bout, "\ttestInt64Shift(%v, %v, %v, %v);\n",
    532 				a, b, a.LeftShift64(b), a.RightShift64(b))
    533 		}
    534 		fmt.Fprintf(bout, "}\n")
    535 	}
    536 
    537 	for _, a := range uint64Values {
    538 		fmt.Fprintf(bout, "func test%v() {\n", ntest)
    539 		ntest++
    540 		fmt.Fprintf(bout, "\ttestUint64Unary(%v, %v, %v, %v);\n", a, a, a.Com(), a.Neg())
    541 		for _, b := range uint64Values {
    542 			var div, mod Uint64
    543 			dodiv := false
    544 			var zero Uint64
    545 			if b.Cmp(zero) != 0 {	// b != 0
    546 				div, mod = a.DivMod(b)
    547 				dodiv = true
    548 			}
    549 			fmt.Fprintf(bout, "\ttestUint64Binary(%v, %v, %v, %v, %v, %v, %v, %v, %v, %v, %v, %v);\n",
    550 				a, b, a.Plus(b), a.Minus(b), a.Times(b), div, mod,
    551 				a.And(b), a.Or(b), a.Xor(b), a.AndNot(b), dodiv)
    552 		}
    553 		for _, b := range shiftValues {
    554 			fmt.Fprintf(bout, "\ttestUint64Shift(%v, %v, %v, %v);\n",
    555 				a, b, a.LeftShift64(b), a.RightShift64(b))
    556 		}
    557 		fmt.Fprintf(bout, "}\n")
    558 	}
    559 }
    560 
    561 // Part 2 is tests of operations involving one variable and one constant.
    562 
    563 const binaryConstL = "func test%vBinaryL%v(b, add, sub, mul, div, mod, and, or, xor, andnot %v, dodiv bool) {\n" +
    564 	"	const a %v = %v;\n" +
    565 	"	const typ = `%s`;\n" +
    566 	"	if n, op, want := a + b, `+`, add; n != want { ok=false; println(typ, `const`, a, op, `var`, b, `=`, n, `should be`, want); }\n" +
    567 	"	if n, op, want := a - b, `-`, sub; n != want { ok=false; println(typ, `const`, a, op, `var`, b, `=`, n, `should be`, want); }\n" +
    568 	"	if n, op, want := a * b, `*`, mul; n != want { ok=false; println(typ, `const`, a, op, `var`, b, `=`, n, `should be`, want); }\n" +
    569 	"	if dodiv {\n" +
    570 	"		if n, op, want := a / b, `/`, div; n != want { ok=false; println(typ, `const`, a, op, `var`, b, `=`, n, `should be`, want); }\n" +
    571 	"		if n, op, want := a %% b, `%%`, mod; n != want { ok=false; println(typ, `const`, a, op, `var`, b, `=`, n, `should be`, want); }\n" +
    572 	"	}\n" +
    573 	"	if n, op, want := a & b, `&`, and; n != want { ok=false; println(typ, `const`, a, op, `var`, b, `=`, n, `should be`, want); }\n" +
    574 	"	if n, op, want := a | b, `|`, or; n != want { ok=false; println(typ, `const`, a, op, `var`, b, `=`, n, `should be`, want); }\n" +
    575 	"	if n, op, want := a ^ b, `^`, xor; n != want { ok=false; println(typ, `const`, a, op, `var`, b, `=`, n, `should be`, want); }\n" +
    576 	"	if n, op, want := a &^ b, `&^`, andnot; n != want { ok=false; println(typ, `const`, a, op, `var`, b, `=`, n, `should be`, want); }\n" +
    577 	"}\n" +
    578 	"\n"
    579 
    580 const binaryConstR = "func test%vBinaryR%v(a, add, sub, mul, div, mod, and, or, xor, andnot %v, dodiv bool) {\n" +
    581 	"	const b %v = %v;\n" +
    582 	"	const typ = `%s`;\n" +
    583 	"	if n, op, want := a + b, `+`, add; n != want { ok=false; println(typ, `var`, a, op, `const`, b, `=`, n, `should be`, want); }\n" +
    584 	"	if n, op, want := a - b, `-`, sub; n != want { ok=false; println(typ, `var`, a, op, `const`, b, `=`, n, `should be`, want); }\n" +
    585 	"	if n, op, want := a * b, `*`, mul; n != want { ok=false; println(typ, `var`, a, op, `const`, b, `=`, n, `should be`, want); }\n" +
    586 	"	if dodiv {\n" +
    587 	"		if n, op, want := a / b, `/`, div; n != want { ok=false; println(typ, `var`, a, op, `const`, b, `=`, n, `should be`, want); }\n" +
    588 	"		if n, op, want := a %% b, `%%`, mod; n != want { ok=false; println(typ, `var`, a, op, `const`, b, `=`, n, `should be`, want); }\n" +
    589 	"	}\n" +
    590 	"	if n, op, want := a & b, `&`, and; n != want { ok=false; println(typ, `var`, a, op, `const`, b, `=`, n, `should be`, want); }\n" +
    591 	"	if n, op, want := a | b, `|`, or; n != want { ok=false; println(typ, `var`, a, op, `const`, b, `=`, n, `should be`, want); }\n" +
    592 	"	if n, op, want := a ^ b, `^`, xor; n != want { ok=false; println(typ, `var`, a, op, `const`, b, `=`, n, `should be`, want); }\n" +
    593 	"	if n, op, want := a &^ b, `&^`, andnot; n != want { ok=false; println(typ, `var`, a, op, `const`, b, `=`, n, `should be`, want); }\n" +
    594 	"}\n" +
    595 	"\n"
    596 
    597 const binaryConstR0 = "func test%vBinaryR%v(a, add, sub, mul, div, mod, and, or, xor, andnot %v, dodiv bool) {\n" +
    598 	"	const b %v = %v;\n" +
    599 	"	const typ = `%s`;\n" +
    600 	"	if n, op, want := a + b, `+`, add; n != want { ok=false; println(typ, `var`, a, op, `const`, b, `=`, n, `should be`, want); }\n" +
    601 	"	if n, op, want := a - b, `-`, sub; n != want { ok=false; println(typ, `var`, a, op, `const`, b, `=`, n, `should be`, want); }\n" +
    602 	"	if n, op, want := a * b, `*`, mul; n != want { ok=false; println(typ, `var`, a, op, `const`, b, `=`, n, `should be`, want); }\n" +
    603 	"	if n, op, want := a & b, `&`, and; n != want { ok=false; println(typ, `var`, a, op, `const`, b, `=`, n, `should be`, want); }\n" +
    604 	"	if n, op, want := a | b, `|`, or; n != want { ok=false; println(typ, `var`, a, op, `const`, b, `=`, n, `should be`, want); }\n" +
    605 	"	if n, op, want := a ^ b, `^`, xor; n != want { ok=false; println(typ, `var`, a, op, `const`, b, `=`, n, `should be`, want); }\n" +
    606 	"	if n, op, want := a &^ b, `&^`, andnot; n != want { ok=false; println(typ, `var`, a, op, `const`, b, `=`, n, `should be`, want); }\n" +
    607 	"}\n" +
    608 	"\n"
    609 
    610 const shiftConstL = "func test%vShiftL%v(b uint64, left, right %v) {\n" +
    611 	"	const a %v = %v;\n" +
    612 	"	const typ = `%s`;\n" +
    613 	"	if n, op, s, want := a << b, `<<`, b, left; n != want { ok=false; println(typ, `const`, a, op, `var`, s, `=`, n, `should be`, want); }\n" +
    614 	"	if n, op, s, want := a >> b, `>>`, b, right; n != want { ok=false; println(typ, `const`, a, op, `var`, s, `=`, n, `should be`, want); }\n" +
    615 	"	if uint64(uint32(b)) == b {\n" +
    616 	"		b := uint32(b);\n" +
    617 	"		if n, op, s, want := a << b, `<<`, b, left; n != want { ok=false; println(typ, `const`, a, op, `var`, s, `=`, n, `should be`, want); }\n" +
    618 	"		if n, op, s, want := a >> b, `>>`, b, right; n != want { ok=false; println(typ, `const`, a, op, `var`, s, `=`, n, `should be`, want); }\n" +
    619 	"	}\n" +
    620 	"}\n"
    621 
    622 const shiftConstR = "func test%vShiftR%v(a, left, right %v) {\n" +
    623 	"	const b uint64 = %v;\n" +
    624 	"	const typ = `%s`;\n" +
    625 	"	if n, op, s, want := a << b, `<<`, b, left; n != want { ok=false; println(typ, `var`, a, op, `const`, s, `=`, n, `should be`, want); }\n" +
    626 	"	if n, op, s, want := a >> b, `>>`, b, right; n != want { ok=false; println(typ, `var`, a, op, `const`, s, `=`, n, `should be`, want); }\n" +
    627 	"	if b & 0xffffffff == b {\n" +
    628 	"		const b = uint32(b & 0xffffffff);\n" +
    629 	"		if n, op, s, want := a << b, `<<`, b, left; n != want { ok=false; println(typ, `var`, a, op, `const`, s, `=`, n, `should be`, want); }\n" +
    630 	"		if n, op, s, want := a >> b, `>>`, b, right; n != want { ok=false; println(typ, `var`, a, op, `const`, s, `=`, n, `should be`, want); }\n" +
    631 	"	}\n" +
    632 	"}\n"
    633 
    634 func constTests() {
    635 	for i, a := range int64Values {
    636 		fmt.Fprintf(bout, binaryConstL, "Int64", i, "int64", "int64", a, "int64")
    637 		if a.hi == 0 && a.lo == 0 {
    638 			fmt.Fprintf(bout, binaryConstR0, "Int64", i, "int64", "int64", a, "int64")
    639 		} else {
    640 			fmt.Fprintf(bout, binaryConstR, "Int64", i, "int64", "int64", a, "int64")
    641 		}
    642 		fmt.Fprintf(bout, shiftConstL, "Int64", i, "int64", "int64", a, "int64")
    643 	}
    644 	for i, a := range uint64Values {
    645 		fmt.Fprintf(bout, binaryConstL, "Uint64", i, "uint64", "uint64", a, "uint64")
    646 		if a.hi == 0 && a.lo == 0 {
    647 			fmt.Fprintf(bout, binaryConstR0, "Uint64", i, "uint64", "uint64", a, "uint64")
    648 		} else {
    649 			fmt.Fprintf(bout, binaryConstR, "Uint64", i, "uint64", "uint64", a, "uint64")
    650 		}
    651 		fmt.Fprintf(bout, shiftConstL, "Uint64", i, "uint64", "uint64", a, "uint64")
    652 	}
    653 	for i, a := range shiftValues {
    654 		fmt.Fprintf(bout, shiftConstR, "Int64", i, "int64", a, "int64")
    655 		fmt.Fprintf(bout, shiftConstR, "Uint64", i, "uint64", a, "uint64")
    656 	}
    657 	for i, a := range int64Values {
    658 		fmt.Fprintf(bout, "func test%v() {\n", ntest)
    659 		ntest++
    660 		for j, b := range int64Values {
    661 			var div, mod Int64
    662 			dodiv := false
    663 			var zero Int64
    664 			if b.Cmp(zero) != 0 {	// b != 0
    665 				// Can't divide by zero but also can't divide -0x8000...000 by -1.
    666 				var bigneg = Int64{-0x80000000, 0}
    667 				var minus1 = Int64{-1, ^uint32(0)}
    668 				if a.Cmp(bigneg) != 0 || b.Cmp(minus1) != 0 {	// a != -1<<63 || b != -1
    669 					div, mod = a.DivMod(b)
    670 					dodiv = true
    671 				}
    672 			}
    673 			fmt.Fprintf(bout, "\ttestInt64BinaryL%v(%v, %v, %v, %v, %v, %v, %v, %v, %v, %v, %v);\n",
    674 				i, b, a.Plus(b), a.Minus(b), a.Times(b), div, mod,
    675 				a.And(b), a.Or(b), a.Xor(b), a.AndNot(b), dodiv)
    676 			fmt.Fprintf(bout, "\ttestInt64BinaryR%v(%v, %v, %v, %v, %v, %v, %v, %v, %v, %v, %v);\n",
    677 				j, a, a.Plus(b), a.Minus(b), a.Times(b), div, mod,
    678 				a.And(b), a.Or(b), a.Xor(b), a.AndNot(b), dodiv)
    679 		}
    680 		for j, b := range shiftValues {
    681 			fmt.Fprintf(bout, "\ttestInt64ShiftL%v(%v, %v, %v);\n",
    682 				i, b, a.LeftShift64(b), a.RightShift64(b))
    683 			fmt.Fprintf(bout, "\ttestInt64ShiftR%v(%v, %v, %v);\n",
    684 				j, a, a.LeftShift64(b), a.RightShift64(b))
    685 		}
    686 		fmt.Fprintf(bout, "}\n")
    687 	}
    688 	for i, a := range uint64Values {
    689 		fmt.Fprintf(bout, "func test%v() {\n", ntest)
    690 		ntest++
    691 		for j, b := range uint64Values {
    692 			var div, mod Uint64
    693 			dodiv := false
    694 			var zero Uint64
    695 			if b.Cmp(zero) != 0 {	// b != 0
    696 				div, mod = a.DivMod(b)
    697 				dodiv = true
    698 			}
    699 			fmt.Fprintf(bout, "\ttestUint64BinaryL%v(%v, %v, %v, %v, %v, %v, %v, %v, %v, %v, %v);\n",
    700 				i, b, a.Plus(b), a.Minus(b), a.Times(b), div, mod,
    701 				a.And(b), a.Or(b), a.Xor(b), a.AndNot(b), dodiv)
    702 			fmt.Fprintf(bout, "\ttestUint64BinaryR%v(%v, %v, %v, %v, %v, %v, %v, %v, %v, %v, %v);\n",
    703 				j, a, a.Plus(b), a.Minus(b), a.Times(b), div, mod,
    704 				a.And(b), a.Or(b), a.Xor(b), a.AndNot(b), dodiv)
    705 		}
    706 		for j, b := range shiftValues {
    707 			fmt.Fprintf(bout, "\ttestUint64ShiftL%v(%v, %v, %v);\n",
    708 				i, b, a.LeftShift64(b), a.RightShift64(b))
    709 			fmt.Fprintf(bout, "\ttestUint64ShiftR%v(%v, %v, %v);\n",
    710 				j, a, a.LeftShift64(b), a.RightShift64(b))
    711 		}
    712 		fmt.Fprintf(bout, "}\n")
    713 	}
    714 }
    715 
    716 func main() {
    717 	bout = bufio.NewWriter(os.Stdout)
    718 	varTests()
    719 	constTests()
    720 
    721 	fmt.Fprintf(bout, "func main() {\n")
    722 	for i := 0; i < ntest; i++ {
    723 		fmt.Fprintf(bout, "\ttest%v();\n", i)
    724 	}
    725 	fmt.Fprintf(bout, "\tif !ok { os.Exit(1) }\n")
    726 	fmt.Fprintf(bout, "}\n")
    727 	bout.Flush()
    728 }
    729