github.com/aloncn/graphics-go@v0.0.1/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 var nn *Node 638 if nr == nil { 639 // copy numeric value to avoid modifying 640 // nl, in case someone still refers to it (e.g. iota). 641 v = nl.Val() 642 643 if wl == TIDEAL { 644 v = copyval(v) 645 } 646 647 switch uint32(n.Op)<<16 | uint32(v.Ctype()) { 648 default: 649 if n.Diag == 0 { 650 Yyerror("illegal constant expression %v %v", Oconv(int(n.Op), 0), nl.Type) 651 n.Diag = 1 652 } 653 return 654 655 case OCONV_ | CTNIL_, 656 OARRAYBYTESTR_ | CTNIL_: 657 if n.Type.Etype == TSTRING { 658 v = tostr(v) 659 nl.Type = n.Type 660 break 661 } 662 fallthrough 663 664 // fall through 665 case OCONV_ | CTINT_, 666 OCONV_ | CTRUNE_, 667 OCONV_ | CTFLT_, 668 OCONV_ | CTSTR_, 669 OCONV_ | CTBOOL_: 670 convlit1(&nl, n.Type, true) 671 672 v = nl.Val() 673 674 case OPLUS_ | CTINT_, 675 OPLUS_ | CTRUNE_: 676 break 677 678 case OMINUS_ | CTINT_, 679 OMINUS_ | CTRUNE_: 680 mpnegfix(v.U.(*Mpint)) 681 682 case OCOM_ | CTINT_, 683 OCOM_ | CTRUNE_: 684 et := Txxx 685 if nl.Type != nil { 686 et = int(nl.Type.Etype) 687 } 688 689 // calculate the mask in b 690 // result will be (a ^ mask) 691 var b Mpint 692 switch et { 693 // signed guys change sign 694 default: 695 Mpmovecfix(&b, -1) 696 697 // unsigned guys invert their bits 698 case TUINT8, 699 TUINT16, 700 TUINT32, 701 TUINT64, 702 TUINT, 703 TUINTPTR: 704 mpmovefixfix(&b, Maxintval[et]) 705 } 706 707 mpxorfixfix(v.U.(*Mpint), &b) 708 709 case OPLUS_ | CTFLT_: 710 break 711 712 case OMINUS_ | CTFLT_: 713 mpnegflt(v.U.(*Mpflt)) 714 715 case OPLUS_ | CTCPLX_: 716 break 717 718 case OMINUS_ | CTCPLX_: 719 mpnegflt(&v.U.(*Mpcplx).Real) 720 mpnegflt(&v.U.(*Mpcplx).Imag) 721 722 case ONOT_ | CTBOOL_: 723 if !v.U.(bool) { 724 goto settrue 725 } 726 goto setfalse 727 } 728 goto ret 729 } 730 if nr.Type == nil { 731 return 732 } 733 if consttype(nr) < 0 { 734 return 735 } 736 wr = int(nr.Type.Etype) 737 if Isint[wr] || Isfloat[wr] || Iscomplex[wr] { 738 wr = TIDEAL 739 } 740 741 // check for compatible general types (numeric, string, etc) 742 if wl != wr { 743 goto illegal 744 } 745 746 // check for compatible types. 747 switch n.Op { 748 // ideal const mixes with anything but otherwise must match. 749 default: 750 if nl.Type.Etype != TIDEAL { 751 defaultlit(&nr, nl.Type) 752 n.Right = nr 753 } 754 755 if nr.Type.Etype != TIDEAL { 756 defaultlit(&nl, nr.Type) 757 n.Left = nl 758 } 759 760 if nl.Type.Etype != nr.Type.Etype { 761 goto illegal 762 } 763 764 // right must be unsigned. 765 // left can be ideal. 766 case OLSH, ORSH: 767 defaultlit(&nr, Types[TUINT]) 768 769 n.Right = nr 770 if nr.Type != nil && (Issigned[nr.Type.Etype] || !Isint[nr.Type.Etype]) { 771 goto illegal 772 } 773 if nl.Val().Ctype() != CTRUNE { 774 nl.SetVal(toint(nl.Val())) 775 } 776 nr.SetVal(toint(nr.Val())) 777 } 778 779 // copy numeric value to avoid modifying 780 // n->left, in case someone still refers to it (e.g. iota). 781 v = nl.Val() 782 783 if wl == TIDEAL { 784 v = copyval(v) 785 } 786 787 rv = nr.Val() 788 789 // convert to common ideal 790 if v.Ctype() == CTCPLX || rv.Ctype() == CTCPLX { 791 v = tocplx(v) 792 rv = tocplx(rv) 793 } 794 795 if v.Ctype() == CTFLT || rv.Ctype() == CTFLT { 796 v = toflt(v) 797 rv = toflt(rv) 798 } 799 800 // Rune and int turns into rune. 801 if v.Ctype() == CTRUNE && rv.Ctype() == CTINT { 802 i := new(Mpint) 803 mpmovefixfix(i, rv.U.(*Mpint)) 804 i.Rune = true 805 rv.U = i 806 } 807 if v.Ctype() == CTINT && rv.Ctype() == CTRUNE { 808 if n.Op == OLSH || n.Op == ORSH { 809 i := new(Mpint) 810 mpmovefixfix(i, rv.U.(*Mpint)) 811 rv.U = i 812 } else { 813 i := new(Mpint) 814 mpmovefixfix(i, v.U.(*Mpint)) 815 i.Rune = true 816 v.U = i 817 } 818 } 819 820 if v.Ctype() != rv.Ctype() { 821 // Use of undefined name as constant? 822 if (v.Ctype() == 0 || rv.Ctype() == 0) && nerrors > 0 { 823 return 824 } 825 Fatalf("constant type mismatch %v(%d) %v(%d)", nl.Type, v.Ctype(), nr.Type, rv.Ctype()) 826 } 827 828 // run op 829 switch uint32(n.Op)<<16 | uint32(v.Ctype()) { 830 default: 831 goto illegal 832 833 case OADD_ | CTINT_, 834 OADD_ | CTRUNE_: 835 mpaddfixfix(v.U.(*Mpint), rv.U.(*Mpint), 0) 836 837 case OSUB_ | CTINT_, 838 OSUB_ | CTRUNE_: 839 mpsubfixfix(v.U.(*Mpint), rv.U.(*Mpint)) 840 841 case OMUL_ | CTINT_, 842 OMUL_ | CTRUNE_: 843 mpmulfixfix(v.U.(*Mpint), rv.U.(*Mpint)) 844 845 case ODIV_ | CTINT_, 846 ODIV_ | CTRUNE_: 847 if mpcmpfixc(rv.U.(*Mpint), 0) == 0 { 848 Yyerror("division by zero") 849 mpsetovf(v.U.(*Mpint)) 850 break 851 } 852 853 mpdivfixfix(v.U.(*Mpint), rv.U.(*Mpint)) 854 855 case OMOD_ | CTINT_, 856 OMOD_ | CTRUNE_: 857 if mpcmpfixc(rv.U.(*Mpint), 0) == 0 { 858 Yyerror("division by zero") 859 mpsetovf(v.U.(*Mpint)) 860 break 861 } 862 863 mpmodfixfix(v.U.(*Mpint), rv.U.(*Mpint)) 864 865 case OLSH_ | CTINT_, 866 OLSH_ | CTRUNE_: 867 mplshfixfix(v.U.(*Mpint), rv.U.(*Mpint)) 868 869 case ORSH_ | CTINT_, 870 ORSH_ | CTRUNE_: 871 mprshfixfix(v.U.(*Mpint), rv.U.(*Mpint)) 872 873 case OOR_ | CTINT_, 874 OOR_ | CTRUNE_: 875 mporfixfix(v.U.(*Mpint), rv.U.(*Mpint)) 876 877 case OAND_ | CTINT_, 878 OAND_ | CTRUNE_: 879 mpandfixfix(v.U.(*Mpint), rv.U.(*Mpint)) 880 881 case OANDNOT_ | CTINT_, 882 OANDNOT_ | CTRUNE_: 883 mpandnotfixfix(v.U.(*Mpint), rv.U.(*Mpint)) 884 885 case OXOR_ | CTINT_, 886 OXOR_ | CTRUNE_: 887 mpxorfixfix(v.U.(*Mpint), rv.U.(*Mpint)) 888 889 case OADD_ | CTFLT_: 890 mpaddfltflt(v.U.(*Mpflt), rv.U.(*Mpflt)) 891 892 case OSUB_ | CTFLT_: 893 mpsubfltflt(v.U.(*Mpflt), rv.U.(*Mpflt)) 894 895 case OMUL_ | CTFLT_: 896 mpmulfltflt(v.U.(*Mpflt), rv.U.(*Mpflt)) 897 898 case ODIV_ | CTFLT_: 899 if mpcmpfltc(rv.U.(*Mpflt), 0) == 0 { 900 Yyerror("division by zero") 901 Mpmovecflt(v.U.(*Mpflt), 1.0) 902 break 903 } 904 905 mpdivfltflt(v.U.(*Mpflt), rv.U.(*Mpflt)) 906 907 // The default case above would print 'ideal % ideal', 908 // which is not quite an ideal error. 909 case OMOD_ | CTFLT_: 910 if n.Diag == 0 { 911 Yyerror("illegal constant expression: floating-point %% operation") 912 n.Diag = 1 913 } 914 915 return 916 917 case OADD_ | CTCPLX_: 918 mpaddfltflt(&v.U.(*Mpcplx).Real, &rv.U.(*Mpcplx).Real) 919 mpaddfltflt(&v.U.(*Mpcplx).Imag, &rv.U.(*Mpcplx).Imag) 920 921 case OSUB_ | CTCPLX_: 922 mpsubfltflt(&v.U.(*Mpcplx).Real, &rv.U.(*Mpcplx).Real) 923 mpsubfltflt(&v.U.(*Mpcplx).Imag, &rv.U.(*Mpcplx).Imag) 924 925 case OMUL_ | CTCPLX_: 926 cmplxmpy(v.U.(*Mpcplx), rv.U.(*Mpcplx)) 927 928 case ODIV_ | CTCPLX_: 929 if mpcmpfltc(&rv.U.(*Mpcplx).Real, 0) == 0 && mpcmpfltc(&rv.U.(*Mpcplx).Imag, 0) == 0 { 930 Yyerror("complex division by zero") 931 Mpmovecflt(&rv.U.(*Mpcplx).Real, 1.0) 932 Mpmovecflt(&rv.U.(*Mpcplx).Imag, 0.0) 933 break 934 } 935 936 cmplxdiv(v.U.(*Mpcplx), rv.U.(*Mpcplx)) 937 938 case OEQ_ | CTNIL_: 939 goto settrue 940 941 case ONE_ | CTNIL_: 942 goto setfalse 943 944 case OEQ_ | CTINT_, 945 OEQ_ | CTRUNE_: 946 if Mpcmpfixfix(v.U.(*Mpint), rv.U.(*Mpint)) == 0 { 947 goto settrue 948 } 949 goto setfalse 950 951 case ONE_ | CTINT_, 952 ONE_ | CTRUNE_: 953 if Mpcmpfixfix(v.U.(*Mpint), rv.U.(*Mpint)) != 0 { 954 goto settrue 955 } 956 goto setfalse 957 958 case OLT_ | CTINT_, 959 OLT_ | CTRUNE_: 960 if Mpcmpfixfix(v.U.(*Mpint), rv.U.(*Mpint)) < 0 { 961 goto settrue 962 } 963 goto setfalse 964 965 case OLE_ | CTINT_, 966 OLE_ | CTRUNE_: 967 if Mpcmpfixfix(v.U.(*Mpint), rv.U.(*Mpint)) <= 0 { 968 goto settrue 969 } 970 goto setfalse 971 972 case OGE_ | CTINT_, 973 OGE_ | CTRUNE_: 974 if Mpcmpfixfix(v.U.(*Mpint), rv.U.(*Mpint)) >= 0 { 975 goto settrue 976 } 977 goto setfalse 978 979 case OGT_ | CTINT_, 980 OGT_ | CTRUNE_: 981 if Mpcmpfixfix(v.U.(*Mpint), rv.U.(*Mpint)) > 0 { 982 goto settrue 983 } 984 goto setfalse 985 986 case OEQ_ | CTFLT_: 987 if mpcmpfltflt(v.U.(*Mpflt), rv.U.(*Mpflt)) == 0 { 988 goto settrue 989 } 990 goto setfalse 991 992 case ONE_ | CTFLT_: 993 if mpcmpfltflt(v.U.(*Mpflt), rv.U.(*Mpflt)) != 0 { 994 goto settrue 995 } 996 goto setfalse 997 998 case OLT_ | CTFLT_: 999 if mpcmpfltflt(v.U.(*Mpflt), rv.U.(*Mpflt)) < 0 { 1000 goto settrue 1001 } 1002 goto setfalse 1003 1004 case OLE_ | CTFLT_: 1005 if mpcmpfltflt(v.U.(*Mpflt), rv.U.(*Mpflt)) <= 0 { 1006 goto settrue 1007 } 1008 goto setfalse 1009 1010 case OGE_ | CTFLT_: 1011 if mpcmpfltflt(v.U.(*Mpflt), rv.U.(*Mpflt)) >= 0 { 1012 goto settrue 1013 } 1014 goto setfalse 1015 1016 case OGT_ | CTFLT_: 1017 if mpcmpfltflt(v.U.(*Mpflt), rv.U.(*Mpflt)) > 0 { 1018 goto settrue 1019 } 1020 goto setfalse 1021 1022 case OEQ_ | 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 ONE_ | CTCPLX_: 1029 if mpcmpfltflt(&v.U.(*Mpcplx).Real, &rv.U.(*Mpcplx).Real) != 0 || mpcmpfltflt(&v.U.(*Mpcplx).Imag, &rv.U.(*Mpcplx).Imag) != 0 { 1030 goto settrue 1031 } 1032 goto setfalse 1033 1034 case OEQ_ | CTSTR_: 1035 if strlit(nl) == strlit(nr) { 1036 goto settrue 1037 } 1038 goto setfalse 1039 1040 case ONE_ | CTSTR_: 1041 if strlit(nl) != strlit(nr) { 1042 goto settrue 1043 } 1044 goto setfalse 1045 1046 case OLT_ | CTSTR_: 1047 if strlit(nl) < strlit(nr) { 1048 goto settrue 1049 } 1050 goto setfalse 1051 1052 case OLE_ | CTSTR_: 1053 if strlit(nl) <= strlit(nr) { 1054 goto settrue 1055 } 1056 goto setfalse 1057 1058 case OGE_ | CTSTR_: 1059 if strlit(nl) >= strlit(nr) { 1060 goto settrue 1061 } 1062 goto setfalse 1063 1064 case OGT_ | CTSTR_: 1065 if strlit(nl) > strlit(nr) { 1066 goto settrue 1067 } 1068 goto setfalse 1069 1070 case OOROR_ | CTBOOL_: 1071 if v.U.(bool) || rv.U.(bool) { 1072 goto settrue 1073 } 1074 goto setfalse 1075 1076 case OANDAND_ | CTBOOL_: 1077 if v.U.(bool) && rv.U.(bool) { 1078 goto settrue 1079 } 1080 goto setfalse 1081 1082 case OEQ_ | CTBOOL_: 1083 if v.U.(bool) == rv.U.(bool) { 1084 goto settrue 1085 } 1086 goto setfalse 1087 1088 case ONE_ | CTBOOL_: 1089 if v.U.(bool) != rv.U.(bool) { 1090 goto settrue 1091 } 1092 goto setfalse 1093 } 1094 1095 goto ret 1096 1097 ret: 1098 norig = saveorig(n) 1099 *n = *nl 1100 1101 // restore value of n->orig. 1102 n.Orig = norig 1103 1104 n.SetVal(v) 1105 1106 // check range. 1107 lno = int(setlineno(n)) 1108 1109 overflow(v, n.Type) 1110 lineno = int32(lno) 1111 1112 // truncate precision for non-ideal float. 1113 if v.Ctype() == CTFLT && n.Type.Etype != TIDEAL { 1114 n.SetVal(Val{truncfltlit(v.U.(*Mpflt), n.Type)}) 1115 } 1116 return 1117 1118 settrue: 1119 nn = Nodbool(true) 1120 nn.Orig = saveorig(n) 1121 if !iscmp[n.Op] { 1122 nn.Type = nl.Type 1123 } 1124 *n = *nn 1125 return 1126 1127 setfalse: 1128 nn = Nodbool(false) 1129 nn.Orig = saveorig(n) 1130 if !iscmp[n.Op] { 1131 nn.Type = nl.Type 1132 } 1133 *n = *nn 1134 return 1135 1136 illegal: 1137 if n.Diag == 0 { 1138 Yyerror("illegal constant expression: %v %v %v", nl.Type, Oconv(int(n.Op), 0), nr.Type) 1139 n.Diag = 1 1140 } 1141 } 1142 1143 func nodlit(v Val) *Node { 1144 n := Nod(OLITERAL, nil, nil) 1145 n.SetVal(v) 1146 switch v.Ctype() { 1147 default: 1148 Fatalf("nodlit ctype %d", v.Ctype()) 1149 1150 case CTSTR: 1151 n.Type = idealstring 1152 1153 case CTBOOL: 1154 n.Type = idealbool 1155 1156 case CTINT, CTRUNE, CTFLT, CTCPLX: 1157 n.Type = Types[TIDEAL] 1158 1159 case CTNIL: 1160 n.Type = Types[TNIL] 1161 } 1162 1163 return n 1164 } 1165 1166 func nodcplxlit(r Val, i Val) *Node { 1167 r = toflt(r) 1168 i = toflt(i) 1169 1170 c := new(Mpcplx) 1171 n := Nod(OLITERAL, nil, nil) 1172 n.Type = Types[TIDEAL] 1173 n.SetVal(Val{c}) 1174 1175 if r.Ctype() != CTFLT || i.Ctype() != CTFLT { 1176 Fatalf("nodcplxlit ctype %d/%d", r.Ctype(), i.Ctype()) 1177 } 1178 1179 mpmovefltflt(&c.Real, r.U.(*Mpflt)) 1180 mpmovefltflt(&c.Imag, i.U.(*Mpflt)) 1181 return n 1182 } 1183 1184 // idealkind returns a constant kind like consttype 1185 // but for an arbitrary "ideal" (untyped constant) expression. 1186 func idealkind(n *Node) Ctype { 1187 if n == nil || !isideal(n.Type) { 1188 return CTxxx 1189 } 1190 1191 switch n.Op { 1192 default: 1193 return CTxxx 1194 1195 case OLITERAL: 1196 return n.Val().Ctype() 1197 1198 // numeric kinds. 1199 case OADD, 1200 OAND, 1201 OANDNOT, 1202 OCOM, 1203 ODIV, 1204 OMINUS, 1205 OMOD, 1206 OMUL, 1207 OSUB, 1208 OXOR, 1209 OOR, 1210 OPLUS: 1211 k1 := idealkind(n.Left) 1212 1213 k2 := idealkind(n.Right) 1214 if k1 > k2 { 1215 return k1 1216 } else { 1217 return k2 1218 } 1219 1220 case OREAL, OIMAG: 1221 return CTFLT 1222 1223 case OCOMPLEX: 1224 return CTCPLX 1225 1226 case OADDSTR: 1227 return CTSTR 1228 1229 case OANDAND, 1230 OEQ, 1231 OGE, 1232 OGT, 1233 OLE, 1234 OLT, 1235 ONE, 1236 ONOT, 1237 OOROR, 1238 OCMPSTR, 1239 OCMPIFACE: 1240 return CTBOOL 1241 1242 // shifts (beware!). 1243 case OLSH, ORSH: 1244 return idealkind(n.Left) 1245 } 1246 } 1247 1248 func defaultlit(np **Node, t *Type) { 1249 n := *np 1250 if n == nil || !isideal(n.Type) { 1251 return 1252 } 1253 1254 if n.Op == OLITERAL { 1255 nn := Nod(OXXX, nil, nil) 1256 *nn = *n 1257 n = nn 1258 *np = n 1259 } 1260 1261 lno := int(setlineno(n)) 1262 ctype := idealkind(n) 1263 var t1 *Type 1264 switch ctype { 1265 default: 1266 if t != nil { 1267 Convlit(np, t) 1268 return 1269 } 1270 1271 if n.Val().Ctype() == CTNIL { 1272 lineno = int32(lno) 1273 if n.Diag == 0 { 1274 Yyerror("use of untyped nil") 1275 n.Diag = 1 1276 } 1277 1278 n.Type = nil 1279 break 1280 } 1281 1282 if n.Val().Ctype() == CTSTR { 1283 t1 := Types[TSTRING] 1284 Convlit(np, t1) 1285 break 1286 } 1287 1288 Yyerror("defaultlit: unknown literal: %v", n) 1289 1290 case CTxxx: 1291 Fatalf("defaultlit: idealkind is CTxxx: %v", Nconv(n, obj.FmtSign)) 1292 1293 case CTBOOL: 1294 t1 := Types[TBOOL] 1295 if t != nil && t.Etype == TBOOL { 1296 t1 = t 1297 } 1298 Convlit(np, t1) 1299 1300 case CTINT: 1301 t1 = Types[TINT] 1302 goto num 1303 1304 case CTRUNE: 1305 t1 = runetype 1306 goto num 1307 1308 case CTFLT: 1309 t1 = Types[TFLOAT64] 1310 goto num 1311 1312 case CTCPLX: 1313 t1 = Types[TCOMPLEX128] 1314 goto num 1315 } 1316 1317 lineno = int32(lno) 1318 return 1319 1320 num: 1321 // Note: n.Val().Ctype() can be CTxxx (not a constant) here 1322 // in the case of an untyped non-constant value, like 1<<i. 1323 v1 := n.Val() 1324 if t != nil { 1325 if Isint[t.Etype] { 1326 t1 = t 1327 v1 = toint(n.Val()) 1328 } else if Isfloat[t.Etype] { 1329 t1 = t 1330 v1 = toflt(n.Val()) 1331 } else if Iscomplex[t.Etype] { 1332 t1 = t 1333 v1 = tocplx(n.Val()) 1334 } 1335 if n.Val().Ctype() != CTxxx { 1336 n.SetVal(v1) 1337 } 1338 } 1339 1340 if n.Val().Ctype() != CTxxx { 1341 overflow(n.Val(), t1) 1342 } 1343 Convlit(np, t1) 1344 lineno = int32(lno) 1345 return 1346 } 1347 1348 // defaultlit on both nodes simultaneously; 1349 // if they're both ideal going in they better 1350 // get the same type going out. 1351 // force means must assign concrete (non-ideal) type. 1352 func defaultlit2(lp **Node, rp **Node, force int) { 1353 l := *lp 1354 r := *rp 1355 if l.Type == nil || r.Type == nil { 1356 return 1357 } 1358 if !isideal(l.Type) { 1359 Convlit(rp, l.Type) 1360 return 1361 } 1362 1363 if !isideal(r.Type) { 1364 Convlit(lp, r.Type) 1365 return 1366 } 1367 1368 if force == 0 { 1369 return 1370 } 1371 if l.Type.Etype == TBOOL { 1372 Convlit(lp, Types[TBOOL]) 1373 Convlit(rp, Types[TBOOL]) 1374 } 1375 1376 lkind := idealkind(l) 1377 rkind := idealkind(r) 1378 if lkind == CTCPLX || rkind == CTCPLX { 1379 Convlit(lp, Types[TCOMPLEX128]) 1380 Convlit(rp, Types[TCOMPLEX128]) 1381 return 1382 } 1383 1384 if lkind == CTFLT || rkind == CTFLT { 1385 Convlit(lp, Types[TFLOAT64]) 1386 Convlit(rp, Types[TFLOAT64]) 1387 return 1388 } 1389 1390 if lkind == CTRUNE || rkind == CTRUNE { 1391 Convlit(lp, runetype) 1392 Convlit(rp, runetype) 1393 return 1394 } 1395 1396 Convlit(lp, Types[TINT]) 1397 Convlit(rp, Types[TINT]) 1398 } 1399 1400 // strlit returns the value of a literal string Node as a string. 1401 func strlit(n *Node) string { 1402 return n.Val().U.(string) 1403 } 1404 1405 func Smallintconst(n *Node) bool { 1406 if n.Op == OLITERAL && Isconst(n, CTINT) && n.Type != nil { 1407 switch Simtype[n.Type.Etype] { 1408 case TINT8, 1409 TUINT8, 1410 TINT16, 1411 TUINT16, 1412 TINT32, 1413 TUINT32, 1414 TBOOL, 1415 TPTR32: 1416 return true 1417 1418 case TIDEAL, TINT64, TUINT64, TPTR64: 1419 if Mpcmpfixfix(n.Val().U.(*Mpint), Minintval[TINT32]) < 0 || Mpcmpfixfix(n.Val().U.(*Mpint), Maxintval[TINT32]) > 0 { 1420 break 1421 } 1422 return true 1423 } 1424 } 1425 1426 return false 1427 } 1428 1429 func nonnegconst(n *Node) int { 1430 if n.Op == OLITERAL && n.Type != nil { 1431 switch Simtype[n.Type.Etype] { 1432 // check negative and 2^31 1433 case TINT8, 1434 TUINT8, 1435 TINT16, 1436 TUINT16, 1437 TINT32, 1438 TUINT32, 1439 TINT64, 1440 TUINT64, 1441 TIDEAL: 1442 if Mpcmpfixfix(n.Val().U.(*Mpint), Minintval[TUINT32]) < 0 || Mpcmpfixfix(n.Val().U.(*Mpint), Maxintval[TINT32]) > 0 { 1443 break 1444 } 1445 return int(Mpgetfix(n.Val().U.(*Mpint))) 1446 } 1447 } 1448 1449 return -1 1450 } 1451 1452 // convert x to type et and back to int64 1453 // for sign extension and truncation. 1454 func iconv(x int64, et EType) int64 { 1455 switch et { 1456 case TINT8: 1457 x = int64(int8(x)) 1458 1459 case TUINT8: 1460 x = int64(uint8(x)) 1461 1462 case TINT16: 1463 x = int64(int16(x)) 1464 1465 case TUINT16: 1466 x = int64(uint64(x)) 1467 1468 case TINT32: 1469 x = int64(int32(x)) 1470 1471 case TUINT32: 1472 x = int64(uint32(x)) 1473 1474 case TINT64, TUINT64: 1475 break 1476 } 1477 1478 return x 1479 } 1480 1481 // Convconst converts constant node n to type t and 1482 // places the result in con. 1483 func (n *Node) Convconst(con *Node, t *Type) { 1484 tt := Simsimtype(t) 1485 1486 // copy the constant for conversion 1487 Nodconst(con, Types[TINT8], 0) 1488 1489 con.Type = t 1490 con.SetVal(n.Val()) 1491 1492 if Isint[tt] { 1493 con.SetVal(Val{new(Mpint)}) 1494 var i int64 1495 switch n.Val().Ctype() { 1496 default: 1497 Fatalf("convconst ctype=%d %v", n.Val().Ctype(), Tconv(t, obj.FmtLong)) 1498 1499 case CTINT, CTRUNE: 1500 i = Mpgetfix(n.Val().U.(*Mpint)) 1501 1502 case CTBOOL: 1503 i = int64(obj.Bool2int(n.Val().U.(bool))) 1504 1505 case CTNIL: 1506 i = 0 1507 } 1508 1509 i = iconv(i, tt) 1510 Mpmovecfix(con.Val().U.(*Mpint), i) 1511 return 1512 } 1513 1514 if Isfloat[tt] { 1515 con.SetVal(toflt(con.Val())) 1516 if con.Val().Ctype() != CTFLT { 1517 Fatalf("convconst ctype=%d %v", con.Val().Ctype(), t) 1518 } 1519 if tt == TFLOAT32 { 1520 con.SetVal(Val{truncfltlit(con.Val().U.(*Mpflt), t)}) 1521 } 1522 return 1523 } 1524 1525 if Iscomplex[tt] { 1526 con.SetVal(tocplx(con.Val())) 1527 if tt == TCOMPLEX64 { 1528 con.Val().U.(*Mpcplx).Real = *truncfltlit(&con.Val().U.(*Mpcplx).Real, Types[TFLOAT32]) 1529 con.Val().U.(*Mpcplx).Imag = *truncfltlit(&con.Val().U.(*Mpcplx).Imag, Types[TFLOAT32]) 1530 } 1531 return 1532 } 1533 1534 Fatalf("convconst %v constant", Tconv(t, obj.FmtLong)) 1535 } 1536 1537 // complex multiply v *= rv 1538 // (a, b) * (c, d) = (a*c - b*d, b*c + a*d) 1539 func cmplxmpy(v *Mpcplx, rv *Mpcplx) { 1540 var ac Mpflt 1541 var bd Mpflt 1542 var bc Mpflt 1543 var ad Mpflt 1544 1545 mpmovefltflt(&ac, &v.Real) 1546 mpmulfltflt(&ac, &rv.Real) // ac 1547 1548 mpmovefltflt(&bd, &v.Imag) 1549 1550 mpmulfltflt(&bd, &rv.Imag) // bd 1551 1552 mpmovefltflt(&bc, &v.Imag) 1553 1554 mpmulfltflt(&bc, &rv.Real) // bc 1555 1556 mpmovefltflt(&ad, &v.Real) 1557 1558 mpmulfltflt(&ad, &rv.Imag) // ad 1559 1560 mpmovefltflt(&v.Real, &ac) 1561 1562 mpsubfltflt(&v.Real, &bd) // ac-bd 1563 1564 mpmovefltflt(&v.Imag, &bc) 1565 1566 mpaddfltflt(&v.Imag, &ad) // bc+ad 1567 } 1568 1569 // complex divide v /= rv 1570 // (a, b) / (c, d) = ((a*c + b*d), (b*c - a*d))/(c*c + d*d) 1571 func cmplxdiv(v *Mpcplx, rv *Mpcplx) { 1572 var ac Mpflt 1573 var bd Mpflt 1574 var bc Mpflt 1575 var ad Mpflt 1576 var cc_plus_dd Mpflt 1577 1578 mpmovefltflt(&cc_plus_dd, &rv.Real) 1579 mpmulfltflt(&cc_plus_dd, &rv.Real) // cc 1580 1581 mpmovefltflt(&ac, &rv.Imag) 1582 1583 mpmulfltflt(&ac, &rv.Imag) // dd 1584 1585 mpaddfltflt(&cc_plus_dd, &ac) // cc+dd 1586 1587 mpmovefltflt(&ac, &v.Real) 1588 1589 mpmulfltflt(&ac, &rv.Real) // ac 1590 1591 mpmovefltflt(&bd, &v.Imag) 1592 1593 mpmulfltflt(&bd, &rv.Imag) // bd 1594 1595 mpmovefltflt(&bc, &v.Imag) 1596 1597 mpmulfltflt(&bc, &rv.Real) // bc 1598 1599 mpmovefltflt(&ad, &v.Real) 1600 1601 mpmulfltflt(&ad, &rv.Imag) // ad 1602 1603 mpmovefltflt(&v.Real, &ac) 1604 1605 mpaddfltflt(&v.Real, &bd) // ac+bd 1606 mpdivfltflt(&v.Real, &cc_plus_dd) // (ac+bd)/(cc+dd) 1607 1608 mpmovefltflt(&v.Imag, &bc) 1609 1610 mpsubfltflt(&v.Imag, &ad) // bc-ad 1611 mpdivfltflt(&v.Imag, &cc_plus_dd) // (bc+ad)/(cc+dd) 1612 } 1613 1614 // Is n a Go language constant (as opposed to a compile-time constant)? 1615 // Expressions derived from nil, like string([]byte(nil)), while they 1616 // may be known at compile time, are not Go language constants. 1617 // Only called for expressions known to evaluated to compile-time 1618 // constants. 1619 func isgoconst(n *Node) bool { 1620 if n.Orig != nil { 1621 n = n.Orig 1622 } 1623 1624 switch n.Op { 1625 case OADD, 1626 OADDSTR, 1627 OAND, 1628 OANDAND, 1629 OANDNOT, 1630 OCOM, 1631 ODIV, 1632 OEQ, 1633 OGE, 1634 OGT, 1635 OLE, 1636 OLSH, 1637 OLT, 1638 OMINUS, 1639 OMOD, 1640 OMUL, 1641 ONE, 1642 ONOT, 1643 OOR, 1644 OOROR, 1645 OPLUS, 1646 ORSH, 1647 OSUB, 1648 OXOR, 1649 OIOTA, 1650 OCOMPLEX, 1651 OREAL, 1652 OIMAG: 1653 if isgoconst(n.Left) && (n.Right == nil || isgoconst(n.Right)) { 1654 return true 1655 } 1656 1657 case OCONV: 1658 if okforconst[n.Type.Etype] && isgoconst(n.Left) { 1659 return true 1660 } 1661 1662 case OLEN, OCAP: 1663 l := n.Left 1664 if isgoconst(l) { 1665 return true 1666 } 1667 1668 // Special case: len/cap is constant when applied to array or 1669 // pointer to array when the expression does not contain 1670 // function calls or channel receive operations. 1671 t := l.Type 1672 1673 if t != nil && Isptr[t.Etype] { 1674 t = t.Type 1675 } 1676 if Isfixedarray(t) && !hascallchan(l) { 1677 return true 1678 } 1679 1680 case OLITERAL: 1681 if n.Val().Ctype() != CTNIL { 1682 return true 1683 } 1684 1685 case ONAME: 1686 l := n.Sym.Def 1687 if l != nil && l.Op == OLITERAL && n.Val().Ctype() != CTNIL { 1688 return true 1689 } 1690 1691 case ONONAME: 1692 if n.Sym.Def != nil && n.Sym.Def.Op == OIOTA { 1693 return true 1694 } 1695 1696 // Only constant calls are unsafe.Alignof, Offsetof, and Sizeof. 1697 case OCALL: 1698 l := n.Left 1699 1700 for l.Op == OPAREN { 1701 l = l.Left 1702 } 1703 if l.Op != ONAME || l.Sym.Pkg != unsafepkg { 1704 break 1705 } 1706 if l.Sym.Name == "Alignof" || l.Sym.Name == "Offsetof" || l.Sym.Name == "Sizeof" { 1707 return true 1708 } 1709 } 1710 1711 //dump("nonconst", n); 1712 return false 1713 } 1714 1715 func hascallchan(n *Node) bool { 1716 if n == nil { 1717 return false 1718 } 1719 switch n.Op { 1720 case OAPPEND, 1721 OCALL, 1722 OCALLFUNC, 1723 OCALLINTER, 1724 OCALLMETH, 1725 OCAP, 1726 OCLOSE, 1727 OCOMPLEX, 1728 OCOPY, 1729 ODELETE, 1730 OIMAG, 1731 OLEN, 1732 OMAKE, 1733 ONEW, 1734 OPANIC, 1735 OPRINT, 1736 OPRINTN, 1737 OREAL, 1738 ORECOVER, 1739 ORECV: 1740 return true 1741 } 1742 1743 if hascallchan(n.Left) || hascallchan(n.Right) { 1744 return true 1745 } 1746 1747 for l := n.List; l != nil; l = l.Next { 1748 if hascallchan(l.N) { 1749 return true 1750 } 1751 } 1752 for l := n.Rlist; l != nil; l = l.Next { 1753 if hascallchan(l.N) { 1754 return true 1755 } 1756 } 1757 1758 return false 1759 }