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