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