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 13package main 14 15import ( 16 "bufio" 17 "fmt" 18 "os" 19) 20 21var 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 27type Uint64 struct { 28 hi uint32 29 lo uint32 30} 31 32type Int64 struct { 33 hi int32 34 lo uint32 35} 36 37func (a Uint64) Int64() (c Int64) { 38 c.hi = int32(a.hi) 39 c.lo = a.lo 40 return 41} 42 43func (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 57func (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 72func (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 87func (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 94func (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 101func (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 110func (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 119func (a Uint64) Neg() (c Uint64) { 120 var zero Uint64 121 return zero.Minus(a) 122} 123 124func (a Uint64) Com() (c Uint64) { 125 c.hi = ^a.hi 126 c.lo = ^a.lo 127 return 128} 129 130func (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 148func (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 158func (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 167func (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 184func (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 190func (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 196func (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 202func (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 208func (a Uint64) String() string { return fmt.Sprintf("%#x%08x", a.hi, a.lo) } 209 210func (a Int64) Uint64() (c Uint64) { 211 c.hi = uint32(a.hi) 212 c.lo = a.lo 213 return 214} 215 216func (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 233func (a Int64) LeftShift(b uint) (c Int64) { return a.Uint64().LeftShift(b).Int64() } 234 235func (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 250func (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 257func (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 264func (a Int64) Plus(b Int64) (c Int64) { return a.Uint64().Plus(b.Uint64()).Int64() } 265 266func (a Int64) Minus(b Int64) (c Int64) { return a.Uint64().Minus(b.Uint64()).Int64() } 267 268func (a Int64) Neg() (c Int64) { return a.Uint64().Neg().Int64() } 269 270func (a Int64) Com() (c Int64) { return a.Uint64().Com().Int64() } 271 272func (a Int64) Times(b Int64) (c Int64) { return a.Uint64().Times(b.Uint64()).Int64() } 273 274func (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 302func (a Int64) And(b Int64) (c Int64) { return a.Uint64().And(b.Uint64()).Int64() } 303 304func (a Int64) AndNot(b Int64) (c Int64) { return a.Uint64().AndNot(b.Uint64()).Int64() } 305 306func (a Int64) Or(b Int64) (c Int64) { return a.Uint64().Or(b.Uint64()).Int64() } 307 308func (a Int64) Xor(b Int64) (c Int64) { return a.Uint64().Xor(b.Uint64()).Int64() } 309 310func (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 317var 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 354var 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 379var 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 404var 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 409const 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 507func 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 563const 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 580const 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 597const shiftConstL = "func test%vShiftL%v(b uint64, left, right %v) {\n" + 598 " const a %v = %v;\n" + 599 " const typ = `%s`;\n" + 600 " 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" + 601 " 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" + 602 " if uint64(uint32(b)) == b {\n" + 603 " b := uint32(b);\n" + 604 " 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" + 605 " 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" + 606 " }\n" + 607 "}\n" 608 609const shiftConstR = "func test%vShiftR%v(a, left, right %v) {\n" + 610 " const b uint64 = %v;\n" + 611 " const typ = `%s`;\n" + 612 " 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" + 613 " 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" + 614 " if b & 0xffffffff == b {\n" + 615 " const b = uint32(b & 0xffffffff);\n" + 616 " 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" + 617 " 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" + 618 " }\n" + 619 "}\n" 620 621func constTests() { 622 for i, a := range int64Values { 623 fmt.Fprintf(bout, binaryConstL, "Int64", i, "int64", "int64", a, "int64") 624 fmt.Fprintf(bout, binaryConstR, "Int64", i, "int64", "int64", a, "int64") 625 fmt.Fprintf(bout, shiftConstL, "Int64", i, "int64", "int64", a, "int64") 626 } 627 for i, a := range uint64Values { 628 fmt.Fprintf(bout, binaryConstL, "Uint64", i, "uint64", "uint64", a, "uint64") 629 fmt.Fprintf(bout, binaryConstR, "Uint64", i, "uint64", "uint64", a, "uint64") 630 fmt.Fprintf(bout, shiftConstL, "Uint64", i, "uint64", "uint64", a, "uint64") 631 } 632 for i, a := range shiftValues { 633 fmt.Fprintf(bout, shiftConstR, "Int64", i, "int64", a, "int64") 634 fmt.Fprintf(bout, shiftConstR, "Uint64", i, "uint64", a, "uint64") 635 } 636 for i, a := range int64Values { 637 fmt.Fprintf(bout, "func test%v() {\n", ntest) 638 ntest++ 639 for j, b := range int64Values { 640 var div, mod Int64 641 dodiv := false 642 var zero Int64 643 if b.Cmp(zero) != 0 { // b != 0 644 // Can't divide by zero but also can't divide -0x8000...000 by -1. 645 var bigneg = Int64{-0x80000000, 0} 646 var minus1 = Int64{-1, ^uint32(0)} 647 if a.Cmp(bigneg) != 0 || b.Cmp(minus1) != 0 { // a != -1<<63 || b != -1 648 div, mod = a.DivMod(b) 649 dodiv = true 650 } 651 } 652 fmt.Fprintf(bout, "\ttestInt64BinaryL%v(%v, %v, %v, %v, %v, %v, %v, %v, %v, %v, %v);\n", 653 i, b, a.Plus(b), a.Minus(b), a.Times(b), div, mod, 654 a.And(b), a.Or(b), a.Xor(b), a.AndNot(b), dodiv) 655 fmt.Fprintf(bout, "\ttestInt64BinaryR%v(%v, %v, %v, %v, %v, %v, %v, %v, %v, %v, %v);\n", 656 j, a, a.Plus(b), a.Minus(b), a.Times(b), div, mod, 657 a.And(b), a.Or(b), a.Xor(b), a.AndNot(b), dodiv) 658 } 659 for j, b := range shiftValues { 660 fmt.Fprintf(bout, "\ttestInt64ShiftL%v(%v, %v, %v);\n", 661 i, b, a.LeftShift64(b), a.RightShift64(b)) 662 fmt.Fprintf(bout, "\ttestInt64ShiftR%v(%v, %v, %v);\n", 663 j, a, a.LeftShift64(b), a.RightShift64(b)) 664 } 665 fmt.Fprintf(bout, "}\n") 666 } 667 for i, a := range uint64Values { 668 fmt.Fprintf(bout, "func test%v() {\n", ntest) 669 ntest++ 670 for j, b := range uint64Values { 671 var div, mod Uint64 672 dodiv := false 673 var zero Uint64 674 if b.Cmp(zero) != 0 { // b != 0 675 div, mod = a.DivMod(b) 676 dodiv = true 677 } 678 fmt.Fprintf(bout, "\ttestUint64BinaryL%v(%v, %v, %v, %v, %v, %v, %v, %v, %v, %v, %v);\n", 679 i, b, a.Plus(b), a.Minus(b), a.Times(b), div, mod, 680 a.And(b), a.Or(b), a.Xor(b), a.AndNot(b), dodiv) 681 fmt.Fprintf(bout, "\ttestUint64BinaryR%v(%v, %v, %v, %v, %v, %v, %v, %v, %v, %v, %v);\n", 682 j, a, a.Plus(b), a.Minus(b), a.Times(b), div, mod, 683 a.And(b), a.Or(b), a.Xor(b), a.AndNot(b), dodiv) 684 } 685 for j, b := range shiftValues { 686 fmt.Fprintf(bout, "\ttestUint64ShiftL%v(%v, %v, %v);\n", 687 i, b, a.LeftShift64(b), a.RightShift64(b)) 688 fmt.Fprintf(bout, "\ttestUint64ShiftR%v(%v, %v, %v);\n", 689 j, a, a.LeftShift64(b), a.RightShift64(b)) 690 } 691 fmt.Fprintf(bout, "}\n") 692 } 693} 694 695func main() { 696 bout = bufio.NewWriter(os.Stdout) 697 varTests() 698 constTests() 699 700 fmt.Fprintf(bout, "func main() {\n") 701 for i := 0; i < ntest; i++ { 702 fmt.Fprintf(bout, "\ttest%v();\n", i) 703 } 704 fmt.Fprintf(bout, "\tif !ok { os.Exit(1) }\n") 705 fmt.Fprintf(bout, "}\n") 706 bout.Flush() 707} 708