github.com/rsc/tmp@v0.0.0-20240517235954-6deaab19748b/bootstrap/internal/gc/const.go (about)

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