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