github.com/sean-/go@v0.0.0-20151219100004-97f854cd7bb6/src/cmd/compile/internal/gc/const.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package gc 6 7 import ( 8 "cmd/compile/internal/big" 9 "cmd/internal/obj" 10 "strings" 11 ) 12 13 // IntLiteral returns the Node's literal value as an interger. 14 func (n *Node) IntLiteral() (x int64, ok bool) { 15 switch { 16 case n == nil: 17 return 18 case Isconst(n, CTINT): 19 return n.Int(), true 20 case Isconst(n, CTBOOL): 21 return int64(obj.Bool2int(n.Bool())), true 22 } 23 return 24 } 25 26 // Int returns n as an int. 27 // n must be an integer constant. 28 func (n *Node) Int() int64 { 29 if !Isconst(n, CTINT) { 30 Fatalf("Int(%v)", n) 31 } 32 return Mpgetfix(n.Val().U.(*Mpint)) 33 } 34 35 // SetInt sets n's value to i. 36 // n must be an integer constant. 37 func (n *Node) SetInt(i int64) { 38 if !Isconst(n, CTINT) { 39 Fatalf("SetInt(%v)", n) 40 } 41 Mpmovecfix(n.Val().U.(*Mpint), i) 42 } 43 44 // SetBigInt sets n's value to x. 45 // n must be an integer constant. 46 func (n *Node) SetBigInt(x *big.Int) { 47 if !Isconst(n, CTINT) { 48 Fatalf("SetBigInt(%v)", n) 49 } 50 n.Val().U.(*Mpint).Val.Set(x) 51 } 52 53 // Bool returns n as an bool. 54 // n must be an boolean constant. 55 func (n *Node) Bool() bool { 56 if !Isconst(n, CTBOOL) { 57 Fatalf("Int(%v)", n) 58 } 59 return n.Val().U.(bool) 60 } 61 62 // truncate float literal fv to 32-bit or 64-bit precision 63 // according to type; return truncated value. 64 func truncfltlit(oldv *Mpflt, t *Type) *Mpflt { 65 if t == nil { 66 return oldv 67 } 68 69 var v Val 70 v.U = oldv 71 overflow(v, t) 72 73 fv := newMpflt() 74 mpmovefltflt(fv, oldv) 75 76 // convert large precision literal floating 77 // into limited precision (float64 or float32) 78 switch t.Etype { 79 case TFLOAT64: 80 d := mpgetflt(fv) 81 Mpmovecflt(fv, d) 82 83 case TFLOAT32: 84 d := mpgetflt32(fv) 85 Mpmovecflt(fv, d) 86 } 87 88 return fv 89 } 90 91 // convert n, if literal, to type t. 92 // implicit conversion. 93 func Convlit(np **Node, t *Type) { 94 convlit1(np, t, false) 95 } 96 97 // convert n, if literal, to type t. 98 // return a new node if necessary 99 //(if n is a named constant, can't edit n->type directly). 100 func convlit1(np **Node, t *Type, explicit bool) { 101 n := *np 102 if n == nil || t == nil || n.Type == nil || isideal(t) || n.Type == t { 103 return 104 } 105 if !explicit && !isideal(n.Type) { 106 return 107 } 108 109 if n.Op == OLITERAL { 110 nn := Nod(OXXX, nil, nil) 111 *nn = *n 112 n = nn 113 *np = n 114 } 115 116 switch n.Op { 117 default: 118 if n.Type == idealbool { 119 if t.Etype == TBOOL { 120 n.Type = t 121 } else { 122 n.Type = Types[TBOOL] 123 } 124 } 125 126 if n.Type.Etype == TIDEAL { 127 Convlit(&n.Left, t) 128 Convlit(&n.Right, t) 129 n.Type = t 130 } 131 132 return 133 134 // target is invalid type for a constant? leave alone. 135 case OLITERAL: 136 if !okforconst[t.Etype] && n.Type.Etype != TNIL { 137 defaultlit(&n, nil) 138 *np = n 139 return 140 } 141 142 case OLSH, ORSH: 143 convlit1(&n.Left, t, explicit && isideal(n.Left.Type)) 144 t = n.Left.Type 145 if t != nil && t.Etype == TIDEAL && n.Val().Ctype() != CTINT { 146 n.SetVal(toint(n.Val())) 147 } 148 if t != nil && !Isint[t.Etype] { 149 Yyerror("invalid operation: %v (shift of type %v)", n, t) 150 t = nil 151 } 152 153 n.Type = t 154 return 155 156 case OCOMPLEX: 157 if n.Type.Etype == TIDEAL { 158 switch t.Etype { 159 // If trying to convert to non-complex type, 160 // leave as complex128 and let typechecker complain. 161 default: 162 t = Types[TCOMPLEX128] 163 fallthrough 164 165 //fallthrough 166 case TCOMPLEX128: 167 n.Type = t 168 169 Convlit(&n.Left, Types[TFLOAT64]) 170 Convlit(&n.Right, Types[TFLOAT64]) 171 172 case TCOMPLEX64: 173 n.Type = t 174 Convlit(&n.Left, Types[TFLOAT32]) 175 Convlit(&n.Right, Types[TFLOAT32]) 176 } 177 } 178 179 return 180 } 181 182 // avoided repeated calculations, errors 183 if Eqtype(n.Type, t) { 184 return 185 } 186 187 ct := consttype(n) 188 var et int 189 if ct < 0 { 190 goto bad 191 } 192 193 et = int(t.Etype) 194 if et == TINTER { 195 if ct == CTNIL && n.Type == Types[TNIL] { 196 n.Type = t 197 return 198 } 199 200 defaultlit(np, nil) 201 return 202 } 203 204 switch ct { 205 default: 206 goto bad 207 208 case CTNIL: 209 switch et { 210 default: 211 n.Type = nil 212 goto bad 213 214 // let normal conversion code handle it 215 case TSTRING: 216 return 217 218 case TARRAY: 219 if !Isslice(t) { 220 goto bad 221 } 222 223 case TPTR32, 224 TPTR64, 225 TINTER, 226 TMAP, 227 TCHAN, 228 TFUNC, 229 TUNSAFEPTR: 230 break 231 232 // A nil literal may be converted to uintptr 233 // if it is an unsafe.Pointer 234 case TUINTPTR: 235 if n.Type.Etype == TUNSAFEPTR { 236 n.SetVal(Val{new(Mpint)}) 237 Mpmovecfix(n.Val().U.(*Mpint), 0) 238 } else { 239 goto bad 240 } 241 } 242 243 case CTSTR, CTBOOL: 244 if et != int(n.Type.Etype) { 245 goto bad 246 } 247 248 case CTINT, CTRUNE, CTFLT, CTCPLX: 249 if n.Type.Etype == TUNSAFEPTR && t.Etype != TUINTPTR { 250 goto bad 251 } 252 ct := n.Val().Ctype() 253 if Isint[et] { 254 switch ct { 255 default: 256 goto bad 257 258 case CTCPLX, CTFLT, CTRUNE: 259 n.SetVal(toint(n.Val())) 260 fallthrough 261 262 case CTINT: 263 overflow(n.Val(), t) 264 } 265 } else if Isfloat[et] { 266 switch ct { 267 default: 268 goto bad 269 270 case CTCPLX, CTINT, CTRUNE: 271 n.SetVal(toflt(n.Val())) 272 fallthrough 273 274 case CTFLT: 275 n.SetVal(Val{truncfltlit(n.Val().U.(*Mpflt), t)}) 276 } 277 } else if Iscomplex[et] { 278 switch ct { 279 default: 280 goto bad 281 282 case CTFLT, CTINT, CTRUNE: 283 n.SetVal(tocplx(n.Val())) 284 fallthrough 285 286 case CTCPLX: 287 overflow(n.Val(), t) 288 } 289 } else if et == TSTRING && (ct == CTINT || ct == CTRUNE) && explicit { 290 n.SetVal(tostr(n.Val())) 291 } else { 292 goto bad 293 } 294 } 295 296 n.Type = t 297 return 298 299 bad: 300 if n.Diag == 0 { 301 if !t.Broke { 302 Yyerror("cannot convert %v to type %v", n, t) 303 } 304 n.Diag = 1 305 } 306 307 if isideal(n.Type) { 308 defaultlit(&n, nil) 309 *np = n 310 } 311 } 312 313 func copyval(v Val) Val { 314 switch v.Ctype() { 315 case CTINT, CTRUNE: 316 i := new(Mpint) 317 mpmovefixfix(i, v.U.(*Mpint)) 318 i.Rune = v.U.(*Mpint).Rune 319 v.U = i 320 321 case CTFLT: 322 f := newMpflt() 323 mpmovefltflt(f, v.U.(*Mpflt)) 324 v.U = f 325 326 case CTCPLX: 327 c := new(Mpcplx) 328 mpmovefltflt(&c.Real, &v.U.(*Mpcplx).Real) 329 mpmovefltflt(&c.Imag, &v.U.(*Mpcplx).Imag) 330 v.U = c 331 } 332 333 return v 334 } 335 336 func tocplx(v Val) Val { 337 switch v.Ctype() { 338 case CTINT, CTRUNE: 339 c := new(Mpcplx) 340 Mpmovefixflt(&c.Real, v.U.(*Mpint)) 341 Mpmovecflt(&c.Imag, 0.0) 342 v.U = c 343 344 case CTFLT: 345 c := new(Mpcplx) 346 mpmovefltflt(&c.Real, v.U.(*Mpflt)) 347 Mpmovecflt(&c.Imag, 0.0) 348 v.U = c 349 } 350 351 return v 352 } 353 354 func toflt(v Val) Val { 355 switch v.Ctype() { 356 case CTINT, CTRUNE: 357 f := newMpflt() 358 Mpmovefixflt(f, v.U.(*Mpint)) 359 v.U = f 360 361 case CTCPLX: 362 f := newMpflt() 363 mpmovefltflt(f, &v.U.(*Mpcplx).Real) 364 if mpcmpfltc(&v.U.(*Mpcplx).Imag, 0) != 0 { 365 Yyerror("constant %v%vi truncated to real", Fconv(&v.U.(*Mpcplx).Real, obj.FmtSharp), Fconv(&v.U.(*Mpcplx).Imag, obj.FmtSharp|obj.FmtSign)) 366 } 367 v.U = f 368 } 369 370 return v 371 } 372 373 func toint(v Val) Val { 374 switch v.Ctype() { 375 case CTRUNE: 376 i := new(Mpint) 377 mpmovefixfix(i, v.U.(*Mpint)) 378 v.U = i 379 380 case CTFLT: 381 i := new(Mpint) 382 if f := v.U.(*Mpflt); mpmovefltfix(i, f) < 0 { 383 msg := "constant %v truncated to integer" 384 // provide better error message if mpmovefltfix failed because f was too large 385 if f.Val.IsInt() { 386 msg = "constant %v overflows integer" 387 } 388 Yyerror(msg, Fconv(f, obj.FmtSharp)) 389 } 390 v.U = i 391 392 case CTCPLX: 393 i := new(Mpint) 394 if mpmovefltfix(i, &v.U.(*Mpcplx).Real) < 0 { 395 Yyerror("constant %v%vi truncated to integer", Fconv(&v.U.(*Mpcplx).Real, obj.FmtSharp), Fconv(&v.U.(*Mpcplx).Imag, obj.FmtSharp|obj.FmtSign)) 396 } 397 if mpcmpfltc(&v.U.(*Mpcplx).Imag, 0) != 0 { 398 Yyerror("constant %v%vi truncated to real", Fconv(&v.U.(*Mpcplx).Real, obj.FmtSharp), Fconv(&v.U.(*Mpcplx).Imag, obj.FmtSharp|obj.FmtSign)) 399 } 400 v.U = i 401 } 402 403 return v 404 } 405 406 func doesoverflow(v Val, t *Type) bool { 407 switch v.Ctype() { 408 case CTINT, CTRUNE: 409 if !Isint[t.Etype] { 410 Fatalf("overflow: %v integer constant", t) 411 } 412 if Mpcmpfixfix(v.U.(*Mpint), Minintval[t.Etype]) < 0 || Mpcmpfixfix(v.U.(*Mpint), Maxintval[t.Etype]) > 0 { 413 return true 414 } 415 416 case CTFLT: 417 if !Isfloat[t.Etype] { 418 Fatalf("overflow: %v floating-point constant", t) 419 } 420 if mpcmpfltflt(v.U.(*Mpflt), minfltval[t.Etype]) <= 0 || mpcmpfltflt(v.U.(*Mpflt), maxfltval[t.Etype]) >= 0 { 421 return true 422 } 423 424 case CTCPLX: 425 if !Iscomplex[t.Etype] { 426 Fatalf("overflow: %v complex constant", t) 427 } 428 if mpcmpfltflt(&v.U.(*Mpcplx).Real, minfltval[t.Etype]) <= 0 || mpcmpfltflt(&v.U.(*Mpcplx).Real, maxfltval[t.Etype]) >= 0 || mpcmpfltflt(&v.U.(*Mpcplx).Imag, minfltval[t.Etype]) <= 0 || mpcmpfltflt(&v.U.(*Mpcplx).Imag, maxfltval[t.Etype]) >= 0 { 429 return true 430 } 431 } 432 433 return false 434 } 435 436 func overflow(v Val, t *Type) { 437 // v has already been converted 438 // to appropriate form for t. 439 if t == nil || t.Etype == TIDEAL { 440 return 441 } 442 443 // Only uintptrs may be converted to unsafe.Pointer, which cannot overflow. 444 if t.Etype == TUNSAFEPTR { 445 return 446 } 447 448 if doesoverflow(v, t) { 449 Yyerror("constant %s overflows %v", Vconv(v, 0), t) 450 } 451 } 452 453 func tostr(v Val) Val { 454 switch v.Ctype() { 455 case CTINT, CTRUNE: 456 if Mpcmpfixfix(v.U.(*Mpint), Minintval[TINT]) < 0 || Mpcmpfixfix(v.U.(*Mpint), Maxintval[TINT]) > 0 { 457 Yyerror("overflow in int -> string") 458 } 459 r := uint(Mpgetfix(v.U.(*Mpint))) 460 v = Val{} 461 v.U = string(r) 462 463 case CTFLT: 464 Yyerror("no float -> string") 465 fallthrough 466 467 case CTNIL: 468 v = Val{} 469 v.U = "" 470 } 471 472 return v 473 } 474 475 func consttype(n *Node) Ctype { 476 if n == nil || n.Op != OLITERAL { 477 return -1 478 } 479 return n.Val().Ctype() 480 } 481 482 func Isconst(n *Node, ct Ctype) bool { 483 t := consttype(n) 484 485 // If the caller is asking for CTINT, allow CTRUNE too. 486 // Makes life easier for back ends. 487 return t == ct || (ct == CTINT && t == CTRUNE) 488 } 489 490 func saveorig(n *Node) *Node { 491 if n == n.Orig { 492 // duplicate node for n->orig. 493 n1 := Nod(OLITERAL, nil, nil) 494 495 n.Orig = n1 496 *n1 = *n 497 } 498 499 return n.Orig 500 } 501 502 // if n is constant, rewrite as OLITERAL node. 503 func evconst(n *Node) { 504 // pick off just the opcodes that can be 505 // constant evaluated. 506 switch n.Op { 507 default: 508 return 509 510 case OADD, 511 OAND, 512 OANDAND, 513 OANDNOT, 514 OARRAYBYTESTR, 515 OCOM, 516 ODIV, 517 OEQ, 518 OGE, 519 OGT, 520 OLE, 521 OLSH, 522 OLT, 523 OMINUS, 524 OMOD, 525 OMUL, 526 ONE, 527 ONOT, 528 OOR, 529 OOROR, 530 OPLUS, 531 ORSH, 532 OSUB, 533 OXOR: 534 break 535 536 case OCONV: 537 if n.Type == nil { 538 return 539 } 540 if !okforconst[n.Type.Etype] && n.Type.Etype != TNIL { 541 return 542 } 543 544 // merge adjacent constants in the argument list. 545 case OADDSTR: 546 var nr *Node 547 var nl *Node 548 var l2 *NodeList 549 for l1 := n.List; l1 != nil; l1 = l1.Next { 550 if Isconst(l1.N, CTSTR) && l1.Next != nil && Isconst(l1.Next.N, CTSTR) { 551 // merge from l1 up to but not including l2 552 var strs []string 553 l2 = l1 554 for l2 != nil && Isconst(l2.N, CTSTR) { 555 nr = l2.N 556 strs = append(strs, nr.Val().U.(string)) 557 l2 = l2.Next 558 } 559 560 nl = Nod(OXXX, nil, nil) 561 *nl = *l1.N 562 nl.Orig = nl 563 nl.SetVal(Val{strings.Join(strs, "")}) 564 l1.N = nl 565 l1.Next = l2 566 } 567 } 568 569 // fix list end pointer. 570 for l2 := n.List; l2 != nil; l2 = l2.Next { 571 n.List.End = l2 572 } 573 574 // collapse single-constant list to single constant. 575 if count(n.List) == 1 && Isconst(n.List.N, CTSTR) { 576 n.Op = OLITERAL 577 n.SetVal(n.List.N.Val()) 578 } 579 580 return 581 } 582 583 nl := n.Left 584 if nl == nil || nl.Type == nil { 585 return 586 } 587 if consttype(nl) < 0 { 588 return 589 } 590 wl := int(nl.Type.Etype) 591 if Isint[wl] || Isfloat[wl] || Iscomplex[wl] { 592 wl = TIDEAL 593 } 594 595 // avoid constant conversions in switches below 596 const ( 597 CTINT_ = uint32(CTINT) 598 CTRUNE_ = uint32(CTRUNE) 599 CTFLT_ = uint32(CTFLT) 600 CTCPLX_ = uint32(CTCPLX) 601 CTSTR_ = uint32(CTSTR) 602 CTBOOL_ = uint32(CTBOOL) 603 CTNIL_ = uint32(CTNIL) 604 OCONV_ = uint32(OCONV) << 16 605 OARRAYBYTESTR_ = uint32(OARRAYBYTESTR) << 16 606 OPLUS_ = uint32(OPLUS) << 16 607 OMINUS_ = uint32(OMINUS) << 16 608 OCOM_ = uint32(OCOM) << 16 609 ONOT_ = uint32(ONOT) << 16 610 OLSH_ = uint32(OLSH) << 16 611 ORSH_ = uint32(ORSH) << 16 612 OADD_ = uint32(OADD) << 16 613 OSUB_ = uint32(OSUB) << 16 614 OMUL_ = uint32(OMUL) << 16 615 ODIV_ = uint32(ODIV) << 16 616 OMOD_ = uint32(OMOD) << 16 617 OOR_ = uint32(OOR) << 16 618 OAND_ = uint32(OAND) << 16 619 OANDNOT_ = uint32(OANDNOT) << 16 620 OXOR_ = uint32(OXOR) << 16 621 OEQ_ = uint32(OEQ) << 16 622 ONE_ = uint32(ONE) << 16 623 OLT_ = uint32(OLT) << 16 624 OLE_ = uint32(OLE) << 16 625 OGE_ = uint32(OGE) << 16 626 OGT_ = uint32(OGT) << 16 627 OOROR_ = uint32(OOROR) << 16 628 OANDAND_ = uint32(OANDAND) << 16 629 ) 630 631 nr := n.Right 632 var rv Val 633 var lno int 634 var wr int 635 var v Val 636 var norig *Node 637 if nr == nil { 638 // copy numeric value to avoid modifying 639 // nl, in case someone still refers to it (e.g. iota). 640 v = nl.Val() 641 642 if wl == TIDEAL { 643 v = copyval(v) 644 } 645 646 switch uint32(n.Op)<<16 | uint32(v.Ctype()) { 647 default: 648 if n.Diag == 0 { 649 Yyerror("illegal constant expression %v %v", Oconv(int(n.Op), 0), nl.Type) 650 n.Diag = 1 651 } 652 return 653 654 case OCONV_ | CTNIL_, 655 OARRAYBYTESTR_ | CTNIL_: 656 if n.Type.Etype == TSTRING { 657 v = tostr(v) 658 nl.Type = n.Type 659 break 660 } 661 fallthrough 662 663 // fall through 664 case OCONV_ | CTINT_, 665 OCONV_ | CTRUNE_, 666 OCONV_ | CTFLT_, 667 OCONV_ | CTSTR_: 668 convlit1(&nl, n.Type, true) 669 670 v = nl.Val() 671 672 case OPLUS_ | CTINT_, 673 OPLUS_ | CTRUNE_: 674 break 675 676 case OMINUS_ | CTINT_, 677 OMINUS_ | CTRUNE_: 678 mpnegfix(v.U.(*Mpint)) 679 680 case OCOM_ | CTINT_, 681 OCOM_ | CTRUNE_: 682 et := Txxx 683 if nl.Type != nil { 684 et = int(nl.Type.Etype) 685 } 686 687 // calculate the mask in b 688 // result will be (a ^ mask) 689 var b Mpint 690 switch et { 691 // signed guys change sign 692 default: 693 Mpmovecfix(&b, -1) 694 695 // unsigned guys invert their bits 696 case TUINT8, 697 TUINT16, 698 TUINT32, 699 TUINT64, 700 TUINT, 701 TUINTPTR: 702 mpmovefixfix(&b, Maxintval[et]) 703 } 704 705 mpxorfixfix(v.U.(*Mpint), &b) 706 707 case OPLUS_ | CTFLT_: 708 break 709 710 case OMINUS_ | CTFLT_: 711 mpnegflt(v.U.(*Mpflt)) 712 713 case OPLUS_ | CTCPLX_: 714 break 715 716 case OMINUS_ | CTCPLX_: 717 mpnegflt(&v.U.(*Mpcplx).Real) 718 mpnegflt(&v.U.(*Mpcplx).Imag) 719 720 case ONOT_ | CTBOOL_: 721 if !v.U.(bool) { 722 goto settrue 723 } 724 goto setfalse 725 } 726 goto ret 727 } 728 if nr.Type == nil { 729 return 730 } 731 if consttype(nr) < 0 { 732 return 733 } 734 wr = int(nr.Type.Etype) 735 if Isint[wr] || Isfloat[wr] || Iscomplex[wr] { 736 wr = TIDEAL 737 } 738 739 // check for compatible general types (numeric, string, etc) 740 if wl != wr { 741 goto illegal 742 } 743 744 // check for compatible types. 745 switch n.Op { 746 // ideal const mixes with anything but otherwise must match. 747 default: 748 if nl.Type.Etype != TIDEAL { 749 defaultlit(&nr, nl.Type) 750 n.Right = nr 751 } 752 753 if nr.Type.Etype != TIDEAL { 754 defaultlit(&nl, nr.Type) 755 n.Left = nl 756 } 757 758 if nl.Type.Etype != nr.Type.Etype { 759 goto illegal 760 } 761 762 // right must be unsigned. 763 // left can be ideal. 764 case OLSH, ORSH: 765 defaultlit(&nr, Types[TUINT]) 766 767 n.Right = nr 768 if nr.Type != nil && (Issigned[nr.Type.Etype] || !Isint[nr.Type.Etype]) { 769 goto illegal 770 } 771 if nl.Val().Ctype() != CTRUNE { 772 nl.SetVal(toint(nl.Val())) 773 } 774 nr.SetVal(toint(nr.Val())) 775 } 776 777 // copy numeric value to avoid modifying 778 // n->left, in case someone still refers to it (e.g. iota). 779 v = nl.Val() 780 781 if wl == TIDEAL { 782 v = copyval(v) 783 } 784 785 rv = nr.Val() 786 787 // convert to common ideal 788 if v.Ctype() == CTCPLX || rv.Ctype() == CTCPLX { 789 v = tocplx(v) 790 rv = tocplx(rv) 791 } 792 793 if v.Ctype() == CTFLT || rv.Ctype() == CTFLT { 794 v = toflt(v) 795 rv = toflt(rv) 796 } 797 798 // Rune and int turns into rune. 799 if v.Ctype() == CTRUNE && rv.Ctype() == CTINT { 800 i := new(Mpint) 801 mpmovefixfix(i, rv.U.(*Mpint)) 802 i.Rune = true 803 rv.U = i 804 } 805 if v.Ctype() == CTINT && rv.Ctype() == CTRUNE { 806 if n.Op == OLSH || n.Op == ORSH { 807 i := new(Mpint) 808 mpmovefixfix(i, rv.U.(*Mpint)) 809 rv.U = i 810 } else { 811 i := new(Mpint) 812 mpmovefixfix(i, v.U.(*Mpint)) 813 i.Rune = true 814 v.U = i 815 } 816 } 817 818 if v.Ctype() != rv.Ctype() { 819 // Use of undefined name as constant? 820 if (v.Ctype() == 0 || rv.Ctype() == 0) && nerrors > 0 { 821 return 822 } 823 Fatalf("constant type mismatch %v(%d) %v(%d)", nl.Type, v.Ctype(), nr.Type, rv.Ctype()) 824 } 825 826 // run op 827 switch uint32(n.Op)<<16 | uint32(v.Ctype()) { 828 default: 829 goto illegal 830 831 case OADD_ | CTINT_, 832 OADD_ | CTRUNE_: 833 mpaddfixfix(v.U.(*Mpint), rv.U.(*Mpint), 0) 834 835 case OSUB_ | CTINT_, 836 OSUB_ | CTRUNE_: 837 mpsubfixfix(v.U.(*Mpint), rv.U.(*Mpint)) 838 839 case OMUL_ | CTINT_, 840 OMUL_ | CTRUNE_: 841 mpmulfixfix(v.U.(*Mpint), rv.U.(*Mpint)) 842 843 case ODIV_ | CTINT_, 844 ODIV_ | CTRUNE_: 845 if mpcmpfixc(rv.U.(*Mpint), 0) == 0 { 846 Yyerror("division by zero") 847 mpsetovf(v.U.(*Mpint)) 848 break 849 } 850 851 mpdivfixfix(v.U.(*Mpint), rv.U.(*Mpint)) 852 853 case OMOD_ | CTINT_, 854 OMOD_ | CTRUNE_: 855 if mpcmpfixc(rv.U.(*Mpint), 0) == 0 { 856 Yyerror("division by zero") 857 mpsetovf(v.U.(*Mpint)) 858 break 859 } 860 861 mpmodfixfix(v.U.(*Mpint), rv.U.(*Mpint)) 862 863 case OLSH_ | CTINT_, 864 OLSH_ | CTRUNE_: 865 mplshfixfix(v.U.(*Mpint), rv.U.(*Mpint)) 866 867 case ORSH_ | CTINT_, 868 ORSH_ | CTRUNE_: 869 mprshfixfix(v.U.(*Mpint), rv.U.(*Mpint)) 870 871 case OOR_ | CTINT_, 872 OOR_ | CTRUNE_: 873 mporfixfix(v.U.(*Mpint), rv.U.(*Mpint)) 874 875 case OAND_ | CTINT_, 876 OAND_ | CTRUNE_: 877 mpandfixfix(v.U.(*Mpint), rv.U.(*Mpint)) 878 879 case OANDNOT_ | CTINT_, 880 OANDNOT_ | CTRUNE_: 881 mpandnotfixfix(v.U.(*Mpint), rv.U.(*Mpint)) 882 883 case OXOR_ | CTINT_, 884 OXOR_ | CTRUNE_: 885 mpxorfixfix(v.U.(*Mpint), rv.U.(*Mpint)) 886 887 case OADD_ | CTFLT_: 888 mpaddfltflt(v.U.(*Mpflt), rv.U.(*Mpflt)) 889 890 case OSUB_ | CTFLT_: 891 mpsubfltflt(v.U.(*Mpflt), rv.U.(*Mpflt)) 892 893 case OMUL_ | CTFLT_: 894 mpmulfltflt(v.U.(*Mpflt), rv.U.(*Mpflt)) 895 896 case ODIV_ | CTFLT_: 897 if mpcmpfltc(rv.U.(*Mpflt), 0) == 0 { 898 Yyerror("division by zero") 899 Mpmovecflt(v.U.(*Mpflt), 1.0) 900 break 901 } 902 903 mpdivfltflt(v.U.(*Mpflt), rv.U.(*Mpflt)) 904 905 // The default case above would print 'ideal % ideal', 906 // which is not quite an ideal error. 907 case OMOD_ | CTFLT_: 908 if n.Diag == 0 { 909 Yyerror("illegal constant expression: floating-point %% operation") 910 n.Diag = 1 911 } 912 913 return 914 915 case OADD_ | CTCPLX_: 916 mpaddfltflt(&v.U.(*Mpcplx).Real, &rv.U.(*Mpcplx).Real) 917 mpaddfltflt(&v.U.(*Mpcplx).Imag, &rv.U.(*Mpcplx).Imag) 918 919 case OSUB_ | CTCPLX_: 920 mpsubfltflt(&v.U.(*Mpcplx).Real, &rv.U.(*Mpcplx).Real) 921 mpsubfltflt(&v.U.(*Mpcplx).Imag, &rv.U.(*Mpcplx).Imag) 922 923 case OMUL_ | CTCPLX_: 924 cmplxmpy(v.U.(*Mpcplx), rv.U.(*Mpcplx)) 925 926 case ODIV_ | CTCPLX_: 927 if mpcmpfltc(&rv.U.(*Mpcplx).Real, 0) == 0 && mpcmpfltc(&rv.U.(*Mpcplx).Imag, 0) == 0 { 928 Yyerror("complex division by zero") 929 Mpmovecflt(&rv.U.(*Mpcplx).Real, 1.0) 930 Mpmovecflt(&rv.U.(*Mpcplx).Imag, 0.0) 931 break 932 } 933 934 cmplxdiv(v.U.(*Mpcplx), rv.U.(*Mpcplx)) 935 936 case OEQ_ | CTNIL_: 937 goto settrue 938 939 case ONE_ | CTNIL_: 940 goto setfalse 941 942 case OEQ_ | CTINT_, 943 OEQ_ | CTRUNE_: 944 if Mpcmpfixfix(v.U.(*Mpint), rv.U.(*Mpint)) == 0 { 945 goto settrue 946 } 947 goto setfalse 948 949 case ONE_ | CTINT_, 950 ONE_ | CTRUNE_: 951 if Mpcmpfixfix(v.U.(*Mpint), rv.U.(*Mpint)) != 0 { 952 goto settrue 953 } 954 goto setfalse 955 956 case OLT_ | CTINT_, 957 OLT_ | CTRUNE_: 958 if Mpcmpfixfix(v.U.(*Mpint), rv.U.(*Mpint)) < 0 { 959 goto settrue 960 } 961 goto setfalse 962 963 case OLE_ | CTINT_, 964 OLE_ | CTRUNE_: 965 if Mpcmpfixfix(v.U.(*Mpint), rv.U.(*Mpint)) <= 0 { 966 goto settrue 967 } 968 goto setfalse 969 970 case OGE_ | CTINT_, 971 OGE_ | CTRUNE_: 972 if Mpcmpfixfix(v.U.(*Mpint), rv.U.(*Mpint)) >= 0 { 973 goto settrue 974 } 975 goto setfalse 976 977 case OGT_ | CTINT_, 978 OGT_ | CTRUNE_: 979 if Mpcmpfixfix(v.U.(*Mpint), rv.U.(*Mpint)) > 0 { 980 goto settrue 981 } 982 goto setfalse 983 984 case OEQ_ | CTFLT_: 985 if mpcmpfltflt(v.U.(*Mpflt), rv.U.(*Mpflt)) == 0 { 986 goto settrue 987 } 988 goto setfalse 989 990 case ONE_ | CTFLT_: 991 if mpcmpfltflt(v.U.(*Mpflt), rv.U.(*Mpflt)) != 0 { 992 goto settrue 993 } 994 goto setfalse 995 996 case OLT_ | CTFLT_: 997 if mpcmpfltflt(v.U.(*Mpflt), rv.U.(*Mpflt)) < 0 { 998 goto settrue 999 } 1000 goto setfalse 1001 1002 case OLE_ | CTFLT_: 1003 if mpcmpfltflt(v.U.(*Mpflt), rv.U.(*Mpflt)) <= 0 { 1004 goto settrue 1005 } 1006 goto setfalse 1007 1008 case OGE_ | CTFLT_: 1009 if mpcmpfltflt(v.U.(*Mpflt), rv.U.(*Mpflt)) >= 0 { 1010 goto settrue 1011 } 1012 goto setfalse 1013 1014 case OGT_ | CTFLT_: 1015 if mpcmpfltflt(v.U.(*Mpflt), rv.U.(*Mpflt)) > 0 { 1016 goto settrue 1017 } 1018 goto setfalse 1019 1020 case OEQ_ | CTCPLX_: 1021 if mpcmpfltflt(&v.U.(*Mpcplx).Real, &rv.U.(*Mpcplx).Real) == 0 && mpcmpfltflt(&v.U.(*Mpcplx).Imag, &rv.U.(*Mpcplx).Imag) == 0 { 1022 goto settrue 1023 } 1024 goto setfalse 1025 1026 case ONE_ | CTCPLX_: 1027 if mpcmpfltflt(&v.U.(*Mpcplx).Real, &rv.U.(*Mpcplx).Real) != 0 || mpcmpfltflt(&v.U.(*Mpcplx).Imag, &rv.U.(*Mpcplx).Imag) != 0 { 1028 goto settrue 1029 } 1030 goto setfalse 1031 1032 case OEQ_ | CTSTR_: 1033 if strlit(nl) == strlit(nr) { 1034 goto settrue 1035 } 1036 goto setfalse 1037 1038 case ONE_ | CTSTR_: 1039 if strlit(nl) != strlit(nr) { 1040 goto settrue 1041 } 1042 goto setfalse 1043 1044 case OLT_ | CTSTR_: 1045 if strlit(nl) < strlit(nr) { 1046 goto settrue 1047 } 1048 goto setfalse 1049 1050 case OLE_ | CTSTR_: 1051 if strlit(nl) <= strlit(nr) { 1052 goto settrue 1053 } 1054 goto setfalse 1055 1056 case OGE_ | CTSTR_: 1057 if strlit(nl) >= strlit(nr) { 1058 goto settrue 1059 } 1060 goto setfalse 1061 1062 case OGT_ | CTSTR_: 1063 if strlit(nl) > strlit(nr) { 1064 goto settrue 1065 } 1066 goto setfalse 1067 1068 case OOROR_ | CTBOOL_: 1069 if v.U.(bool) || rv.U.(bool) { 1070 goto settrue 1071 } 1072 goto setfalse 1073 1074 case OANDAND_ | CTBOOL_: 1075 if v.U.(bool) && rv.U.(bool) { 1076 goto settrue 1077 } 1078 goto setfalse 1079 1080 case OEQ_ | CTBOOL_: 1081 if v.U.(bool) == rv.U.(bool) { 1082 goto settrue 1083 } 1084 goto setfalse 1085 1086 case ONE_ | CTBOOL_: 1087 if v.U.(bool) != rv.U.(bool) { 1088 goto settrue 1089 } 1090 goto setfalse 1091 } 1092 1093 goto ret 1094 1095 ret: 1096 norig = saveorig(n) 1097 *n = *nl 1098 1099 // restore value of n->orig. 1100 n.Orig = norig 1101 1102 n.SetVal(v) 1103 1104 // check range. 1105 lno = int(setlineno(n)) 1106 1107 overflow(v, n.Type) 1108 lineno = int32(lno) 1109 1110 // truncate precision for non-ideal float. 1111 if v.Ctype() == CTFLT && n.Type.Etype != TIDEAL { 1112 n.SetVal(Val{truncfltlit(v.U.(*Mpflt), n.Type)}) 1113 } 1114 return 1115 1116 settrue: 1117 norig = saveorig(n) 1118 *n = *Nodbool(true) 1119 n.Orig = norig 1120 return 1121 1122 setfalse: 1123 norig = saveorig(n) 1124 *n = *Nodbool(false) 1125 n.Orig = norig 1126 return 1127 1128 illegal: 1129 if n.Diag == 0 { 1130 Yyerror("illegal constant expression: %v %v %v", nl.Type, Oconv(int(n.Op), 0), nr.Type) 1131 n.Diag = 1 1132 } 1133 } 1134 1135 func nodlit(v Val) *Node { 1136 n := Nod(OLITERAL, nil, nil) 1137 n.SetVal(v) 1138 switch v.Ctype() { 1139 default: 1140 Fatalf("nodlit ctype %d", v.Ctype()) 1141 1142 case CTSTR: 1143 n.Type = idealstring 1144 1145 case CTBOOL: 1146 n.Type = idealbool 1147 1148 case CTINT, CTRUNE, CTFLT, CTCPLX: 1149 n.Type = Types[TIDEAL] 1150 1151 case CTNIL: 1152 n.Type = Types[TNIL] 1153 } 1154 1155 return n 1156 } 1157 1158 func nodcplxlit(r Val, i Val) *Node { 1159 r = toflt(r) 1160 i = toflt(i) 1161 1162 c := new(Mpcplx) 1163 n := Nod(OLITERAL, nil, nil) 1164 n.Type = Types[TIDEAL] 1165 n.SetVal(Val{c}) 1166 1167 if r.Ctype() != CTFLT || i.Ctype() != CTFLT { 1168 Fatalf("nodcplxlit ctype %d/%d", r.Ctype(), i.Ctype()) 1169 } 1170 1171 mpmovefltflt(&c.Real, r.U.(*Mpflt)) 1172 mpmovefltflt(&c.Imag, i.U.(*Mpflt)) 1173 return n 1174 } 1175 1176 // idealkind returns a constant kind like consttype 1177 // but for an arbitrary "ideal" (untyped constant) expression. 1178 func idealkind(n *Node) Ctype { 1179 if n == nil || !isideal(n.Type) { 1180 return CTxxx 1181 } 1182 1183 switch n.Op { 1184 default: 1185 return CTxxx 1186 1187 case OLITERAL: 1188 return n.Val().Ctype() 1189 1190 // numeric kinds. 1191 case OADD, 1192 OAND, 1193 OANDNOT, 1194 OCOM, 1195 ODIV, 1196 OMINUS, 1197 OMOD, 1198 OMUL, 1199 OSUB, 1200 OXOR, 1201 OOR, 1202 OPLUS: 1203 k1 := idealkind(n.Left) 1204 1205 k2 := idealkind(n.Right) 1206 if k1 > k2 { 1207 return k1 1208 } else { 1209 return k2 1210 } 1211 1212 case OREAL, OIMAG: 1213 return CTFLT 1214 1215 case OCOMPLEX: 1216 return CTCPLX 1217 1218 case OADDSTR: 1219 return CTSTR 1220 1221 case OANDAND, 1222 OEQ, 1223 OGE, 1224 OGT, 1225 OLE, 1226 OLT, 1227 ONE, 1228 ONOT, 1229 OOROR, 1230 OCMPSTR, 1231 OCMPIFACE: 1232 return CTBOOL 1233 1234 // shifts (beware!). 1235 case OLSH, ORSH: 1236 return idealkind(n.Left) 1237 } 1238 } 1239 1240 func defaultlit(np **Node, t *Type) { 1241 n := *np 1242 if n == nil || !isideal(n.Type) { 1243 return 1244 } 1245 1246 if n.Op == OLITERAL { 1247 nn := Nod(OXXX, nil, nil) 1248 *nn = *n 1249 n = nn 1250 *np = n 1251 } 1252 1253 lno := int(setlineno(n)) 1254 ctype := idealkind(n) 1255 var t1 *Type 1256 switch ctype { 1257 default: 1258 if t != nil { 1259 Convlit(np, t) 1260 return 1261 } 1262 1263 if n.Val().Ctype() == CTNIL { 1264 lineno = int32(lno) 1265 if n.Diag == 0 { 1266 Yyerror("use of untyped nil") 1267 n.Diag = 1 1268 } 1269 1270 n.Type = nil 1271 break 1272 } 1273 1274 if n.Val().Ctype() == CTSTR { 1275 t1 := Types[TSTRING] 1276 Convlit(np, t1) 1277 break 1278 } 1279 1280 Yyerror("defaultlit: unknown literal: %v", n) 1281 1282 case CTxxx: 1283 Fatalf("defaultlit: idealkind is CTxxx: %v", Nconv(n, obj.FmtSign)) 1284 1285 case CTBOOL: 1286 t1 := Types[TBOOL] 1287 if t != nil && t.Etype == TBOOL { 1288 t1 = t 1289 } 1290 Convlit(np, t1) 1291 1292 case CTINT: 1293 t1 = Types[TINT] 1294 goto num 1295 1296 case CTRUNE: 1297 t1 = runetype 1298 goto num 1299 1300 case CTFLT: 1301 t1 = Types[TFLOAT64] 1302 goto num 1303 1304 case CTCPLX: 1305 t1 = Types[TCOMPLEX128] 1306 goto num 1307 } 1308 1309 lineno = int32(lno) 1310 return 1311 1312 num: 1313 // Note: n.Val().Ctype() can be CTxxx (not a constant) here 1314 // in the case of an untyped non-constant value, like 1<<i. 1315 v1 := n.Val() 1316 if t != nil { 1317 if Isint[t.Etype] { 1318 t1 = t 1319 v1 = toint(n.Val()) 1320 } else if Isfloat[t.Etype] { 1321 t1 = t 1322 v1 = toflt(n.Val()) 1323 } else if Iscomplex[t.Etype] { 1324 t1 = t 1325 v1 = tocplx(n.Val()) 1326 } 1327 if n.Val().Ctype() != CTxxx { 1328 n.SetVal(v1) 1329 } 1330 } 1331 1332 if n.Val().Ctype() != CTxxx { 1333 overflow(n.Val(), t1) 1334 } 1335 Convlit(np, t1) 1336 lineno = int32(lno) 1337 return 1338 } 1339 1340 // defaultlit on both nodes simultaneously; 1341 // if they're both ideal going in they better 1342 // get the same type going out. 1343 // force means must assign concrete (non-ideal) type. 1344 func defaultlit2(lp **Node, rp **Node, force int) { 1345 l := *lp 1346 r := *rp 1347 if l.Type == nil || r.Type == nil { 1348 return 1349 } 1350 if !isideal(l.Type) { 1351 Convlit(rp, l.Type) 1352 return 1353 } 1354 1355 if !isideal(r.Type) { 1356 Convlit(lp, r.Type) 1357 return 1358 } 1359 1360 if force == 0 { 1361 return 1362 } 1363 if l.Type.Etype == TBOOL { 1364 Convlit(lp, Types[TBOOL]) 1365 Convlit(rp, Types[TBOOL]) 1366 } 1367 1368 lkind := idealkind(l) 1369 rkind := idealkind(r) 1370 if lkind == CTCPLX || rkind == CTCPLX { 1371 Convlit(lp, Types[TCOMPLEX128]) 1372 Convlit(rp, Types[TCOMPLEX128]) 1373 return 1374 } 1375 1376 if lkind == CTFLT || rkind == CTFLT { 1377 Convlit(lp, Types[TFLOAT64]) 1378 Convlit(rp, Types[TFLOAT64]) 1379 return 1380 } 1381 1382 if lkind == CTRUNE || rkind == CTRUNE { 1383 Convlit(lp, runetype) 1384 Convlit(rp, runetype) 1385 return 1386 } 1387 1388 Convlit(lp, Types[TINT]) 1389 Convlit(rp, Types[TINT]) 1390 } 1391 1392 // strlit returns the value of a literal string Node as a string. 1393 func strlit(n *Node) string { 1394 return n.Val().U.(string) 1395 } 1396 1397 func Smallintconst(n *Node) bool { 1398 if n.Op == OLITERAL && Isconst(n, CTINT) && n.Type != nil { 1399 switch Simtype[n.Type.Etype] { 1400 case TINT8, 1401 TUINT8, 1402 TINT16, 1403 TUINT16, 1404 TINT32, 1405 TUINT32, 1406 TBOOL, 1407 TPTR32: 1408 return true 1409 1410 case TIDEAL, TINT64, TUINT64, TPTR64: 1411 if Mpcmpfixfix(n.Val().U.(*Mpint), Minintval[TINT32]) < 0 || Mpcmpfixfix(n.Val().U.(*Mpint), Maxintval[TINT32]) > 0 { 1412 break 1413 } 1414 return true 1415 } 1416 } 1417 1418 return false 1419 } 1420 1421 func nonnegconst(n *Node) int { 1422 if n.Op == OLITERAL && n.Type != nil { 1423 switch Simtype[n.Type.Etype] { 1424 // check negative and 2^31 1425 case TINT8, 1426 TUINT8, 1427 TINT16, 1428 TUINT16, 1429 TINT32, 1430 TUINT32, 1431 TINT64, 1432 TUINT64, 1433 TIDEAL: 1434 if Mpcmpfixfix(n.Val().U.(*Mpint), Minintval[TUINT32]) < 0 || Mpcmpfixfix(n.Val().U.(*Mpint), Maxintval[TINT32]) > 0 { 1435 break 1436 } 1437 return int(Mpgetfix(n.Val().U.(*Mpint))) 1438 } 1439 } 1440 1441 return -1 1442 } 1443 1444 // convert x to type et and back to int64 1445 // for sign extension and truncation. 1446 func iconv(x int64, et EType) int64 { 1447 switch et { 1448 case TINT8: 1449 x = int64(int8(x)) 1450 1451 case TUINT8: 1452 x = int64(uint8(x)) 1453 1454 case TINT16: 1455 x = int64(int16(x)) 1456 1457 case TUINT16: 1458 x = int64(uint64(x)) 1459 1460 case TINT32: 1461 x = int64(int32(x)) 1462 1463 case TUINT32: 1464 x = int64(uint32(x)) 1465 1466 case TINT64, TUINT64: 1467 break 1468 } 1469 1470 return x 1471 } 1472 1473 // Convconst converts constant node n to type t and 1474 // places the result in con. 1475 func (n *Node) Convconst(con *Node, t *Type) { 1476 tt := Simsimtype(t) 1477 1478 // copy the constant for conversion 1479 Nodconst(con, Types[TINT8], 0) 1480 1481 con.Type = t 1482 con.SetVal(n.Val()) 1483 1484 if Isint[tt] { 1485 con.SetVal(Val{new(Mpint)}) 1486 var i int64 1487 switch n.Val().Ctype() { 1488 default: 1489 Fatalf("convconst ctype=%d %v", n.Val().Ctype(), Tconv(t, obj.FmtLong)) 1490 1491 case CTINT, CTRUNE: 1492 i = Mpgetfix(n.Val().U.(*Mpint)) 1493 1494 case CTBOOL: 1495 i = int64(obj.Bool2int(n.Val().U.(bool))) 1496 1497 case CTNIL: 1498 i = 0 1499 } 1500 1501 i = iconv(i, tt) 1502 Mpmovecfix(con.Val().U.(*Mpint), i) 1503 return 1504 } 1505 1506 if Isfloat[tt] { 1507 con.SetVal(toflt(con.Val())) 1508 if con.Val().Ctype() != CTFLT { 1509 Fatalf("convconst ctype=%d %v", con.Val().Ctype(), t) 1510 } 1511 if tt == TFLOAT32 { 1512 con.SetVal(Val{truncfltlit(con.Val().U.(*Mpflt), t)}) 1513 } 1514 return 1515 } 1516 1517 if Iscomplex[tt] { 1518 con.SetVal(tocplx(con.Val())) 1519 if tt == TCOMPLEX64 { 1520 con.Val().U.(*Mpcplx).Real = *truncfltlit(&con.Val().U.(*Mpcplx).Real, Types[TFLOAT32]) 1521 con.Val().U.(*Mpcplx).Imag = *truncfltlit(&con.Val().U.(*Mpcplx).Imag, Types[TFLOAT32]) 1522 } 1523 return 1524 } 1525 1526 Fatalf("convconst %v constant", Tconv(t, obj.FmtLong)) 1527 } 1528 1529 // complex multiply v *= rv 1530 // (a, b) * (c, d) = (a*c - b*d, b*c + a*d) 1531 func cmplxmpy(v *Mpcplx, rv *Mpcplx) { 1532 var ac Mpflt 1533 var bd Mpflt 1534 var bc Mpflt 1535 var ad Mpflt 1536 1537 mpmovefltflt(&ac, &v.Real) 1538 mpmulfltflt(&ac, &rv.Real) // ac 1539 1540 mpmovefltflt(&bd, &v.Imag) 1541 1542 mpmulfltflt(&bd, &rv.Imag) // bd 1543 1544 mpmovefltflt(&bc, &v.Imag) 1545 1546 mpmulfltflt(&bc, &rv.Real) // bc 1547 1548 mpmovefltflt(&ad, &v.Real) 1549 1550 mpmulfltflt(&ad, &rv.Imag) // ad 1551 1552 mpmovefltflt(&v.Real, &ac) 1553 1554 mpsubfltflt(&v.Real, &bd) // ac-bd 1555 1556 mpmovefltflt(&v.Imag, &bc) 1557 1558 mpaddfltflt(&v.Imag, &ad) // bc+ad 1559 } 1560 1561 // complex divide v /= rv 1562 // (a, b) / (c, d) = ((a*c + b*d), (b*c - a*d))/(c*c + d*d) 1563 func cmplxdiv(v *Mpcplx, rv *Mpcplx) { 1564 var ac Mpflt 1565 var bd Mpflt 1566 var bc Mpflt 1567 var ad Mpflt 1568 var cc_plus_dd Mpflt 1569 1570 mpmovefltflt(&cc_plus_dd, &rv.Real) 1571 mpmulfltflt(&cc_plus_dd, &rv.Real) // cc 1572 1573 mpmovefltflt(&ac, &rv.Imag) 1574 1575 mpmulfltflt(&ac, &rv.Imag) // dd 1576 1577 mpaddfltflt(&cc_plus_dd, &ac) // cc+dd 1578 1579 mpmovefltflt(&ac, &v.Real) 1580 1581 mpmulfltflt(&ac, &rv.Real) // ac 1582 1583 mpmovefltflt(&bd, &v.Imag) 1584 1585 mpmulfltflt(&bd, &rv.Imag) // bd 1586 1587 mpmovefltflt(&bc, &v.Imag) 1588 1589 mpmulfltflt(&bc, &rv.Real) // bc 1590 1591 mpmovefltflt(&ad, &v.Real) 1592 1593 mpmulfltflt(&ad, &rv.Imag) // ad 1594 1595 mpmovefltflt(&v.Real, &ac) 1596 1597 mpaddfltflt(&v.Real, &bd) // ac+bd 1598 mpdivfltflt(&v.Real, &cc_plus_dd) // (ac+bd)/(cc+dd) 1599 1600 mpmovefltflt(&v.Imag, &bc) 1601 1602 mpsubfltflt(&v.Imag, &ad) // bc-ad 1603 mpdivfltflt(&v.Imag, &cc_plus_dd) // (bc+ad)/(cc+dd) 1604 } 1605 1606 // Is n a Go language constant (as opposed to a compile-time constant)? 1607 // Expressions derived from nil, like string([]byte(nil)), while they 1608 // may be known at compile time, are not Go language constants. 1609 // Only called for expressions known to evaluated to compile-time 1610 // constants. 1611 func isgoconst(n *Node) bool { 1612 if n.Orig != nil { 1613 n = n.Orig 1614 } 1615 1616 switch n.Op { 1617 case OADD, 1618 OADDSTR, 1619 OAND, 1620 OANDAND, 1621 OANDNOT, 1622 OCOM, 1623 ODIV, 1624 OEQ, 1625 OGE, 1626 OGT, 1627 OLE, 1628 OLSH, 1629 OLT, 1630 OMINUS, 1631 OMOD, 1632 OMUL, 1633 ONE, 1634 ONOT, 1635 OOR, 1636 OOROR, 1637 OPLUS, 1638 ORSH, 1639 OSUB, 1640 OXOR, 1641 OIOTA, 1642 OCOMPLEX, 1643 OREAL, 1644 OIMAG: 1645 if isgoconst(n.Left) && (n.Right == nil || isgoconst(n.Right)) { 1646 return true 1647 } 1648 1649 case OCONV: 1650 if okforconst[n.Type.Etype] && isgoconst(n.Left) { 1651 return true 1652 } 1653 1654 case OLEN, OCAP: 1655 l := n.Left 1656 if isgoconst(l) { 1657 return true 1658 } 1659 1660 // Special case: len/cap is constant when applied to array or 1661 // pointer to array when the expression does not contain 1662 // function calls or channel receive operations. 1663 t := l.Type 1664 1665 if t != nil && Isptr[t.Etype] { 1666 t = t.Type 1667 } 1668 if Isfixedarray(t) && !hascallchan(l) { 1669 return true 1670 } 1671 1672 case OLITERAL: 1673 if n.Val().Ctype() != CTNIL { 1674 return true 1675 } 1676 1677 case ONAME: 1678 l := n.Sym.Def 1679 if l != nil && l.Op == OLITERAL && n.Val().Ctype() != CTNIL { 1680 return true 1681 } 1682 1683 case ONONAME: 1684 if n.Sym.Def != nil && n.Sym.Def.Op == OIOTA { 1685 return true 1686 } 1687 1688 // Only constant calls are unsafe.Alignof, Offsetof, and Sizeof. 1689 case OCALL: 1690 l := n.Left 1691 1692 for l.Op == OPAREN { 1693 l = l.Left 1694 } 1695 if l.Op != ONAME || l.Sym.Pkg != unsafepkg { 1696 break 1697 } 1698 if l.Sym.Name == "Alignof" || l.Sym.Name == "Offsetof" || l.Sym.Name == "Sizeof" { 1699 return true 1700 } 1701 } 1702 1703 //dump("nonconst", n); 1704 return false 1705 } 1706 1707 func hascallchan(n *Node) bool { 1708 if n == nil { 1709 return false 1710 } 1711 switch n.Op { 1712 case OAPPEND, 1713 OCALL, 1714 OCALLFUNC, 1715 OCALLINTER, 1716 OCALLMETH, 1717 OCAP, 1718 OCLOSE, 1719 OCOMPLEX, 1720 OCOPY, 1721 ODELETE, 1722 OIMAG, 1723 OLEN, 1724 OMAKE, 1725 ONEW, 1726 OPANIC, 1727 OPRINT, 1728 OPRINTN, 1729 OREAL, 1730 ORECOVER, 1731 ORECV: 1732 return true 1733 } 1734 1735 if hascallchan(n.Left) || hascallchan(n.Right) { 1736 return true 1737 } 1738 1739 for l := n.List; l != nil; l = l.Next { 1740 if hascallchan(l.N) { 1741 return true 1742 } 1743 } 1744 for l := n.Rlist; l != nil; l = l.Next { 1745 if hascallchan(l.N) { 1746 return true 1747 } 1748 } 1749 1750 return false 1751 }