blob: f0b66957f1201bf4c546a640b1e84d00afb84344 [file] [log] [blame]
 // Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package ir import ( "go/constant" "math" "math/big" "cmd/compile/internal/base" "cmd/compile/internal/types" ) func NewBool(b bool) Node { return NewLiteral(constant.MakeBool(b)) } func NewInt(v int64) Node { return NewLiteral(constant.MakeInt64(v)) } func NewString(s string) Node { return NewLiteral(constant.MakeString(s)) } const ( // Maximum size in bits for big.Ints before signaling // overflow and also mantissa precision for big.Floats. ConstPrec = 512 ) func BigFloat(v constant.Value) *big.Float { f := new(big.Float) f.SetPrec(ConstPrec) switch u := constant.Val(v).(type) { case int64: f.SetInt64(u) case *big.Int: f.SetInt(u) case *big.Float: f.Set(u) case *big.Rat: f.SetRat(u) default: base.Fatalf("unexpected: %v", u) } return f } // ConstOverflow reports whether constant value v is too large // to represent with type t. func ConstOverflow(v constant.Value, t *types.Type) bool { switch { case t.IsInteger(): bits := uint(8 * t.Size()) if t.IsUnsigned() { x, ok := constant.Uint64Val(v) return !ok || x>>bits != 0 } x, ok := constant.Int64Val(v) if x < 0 { x = ^x } return !ok || x>>(bits-1) != 0 case t.IsFloat(): switch t.Size() { case 4: f, _ := constant.Float32Val(v) return math.IsInf(float64(f), 0) case 8: f, _ := constant.Float64Val(v) return math.IsInf(f, 0) } case t.IsComplex(): ft := types.FloatForComplex(t) return ConstOverflow(constant.Real(v), ft) || ConstOverflow(constant.Imag(v), ft) } base.Fatalf("ConstOverflow: %v, %v", v, t) panic("unreachable") } // IsConstNode reports whether n is a Go language constant (as opposed to a // compile-time constant). // // Expressions derived from nil, like string([]byte(nil)), while they // may be known at compile time, are not Go language constants. func IsConstNode(n Node) bool { return n.Op() == OLITERAL } func IsSmallIntConst(n Node) bool { if n.Op() == OLITERAL { v, ok := constant.Int64Val(n.Val()) return ok && int64(int32(v)) == v } return false }