github.com/bir3/gocompiler@v0.3.205/src/cmd/compile/internal/ir/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 ir 6 7 import ( 8 "github.com/bir3/gocompiler/src/go/constant" 9 "math" 10 "math/big" 11 12 "github.com/bir3/gocompiler/src/cmd/compile/internal/base" 13 "github.com/bir3/gocompiler/src/cmd/compile/internal/types" 14 ) 15 16 func NewBool(b bool) Node { 17 return NewLiteral(constant.MakeBool(b)) 18 } 19 20 func NewInt(v int64) Node { 21 return NewLiteral(constant.MakeInt64(v)) 22 } 23 24 func NewString(s string) Node { 25 return NewLiteral(constant.MakeString(s)) 26 } 27 28 const ( 29 // Maximum size in bits for big.Ints before signaling 30 // overflow and also mantissa precision for big.Floats. 31 ConstPrec = 512 32 ) 33 34 func BigFloat(v constant.Value) *big.Float { 35 f := new(big.Float) 36 f.SetPrec(ConstPrec) 37 switch u := constant.Val(v).(type) { 38 case int64: 39 f.SetInt64(u) 40 case *big.Int: 41 f.SetInt(u) 42 case *big.Float: 43 f.Set(u) 44 case *big.Rat: 45 f.SetRat(u) 46 default: 47 base.Fatalf("unexpected: %v", u) 48 } 49 return f 50 } 51 52 // ConstOverflow reports whether constant value v is too large 53 // to represent with type t. 54 func ConstOverflow(v constant.Value, t *types.Type) bool { 55 switch { 56 case t.IsInteger(): 57 bits := uint(8 * t.Size()) 58 if t.IsUnsigned() { 59 x, ok := constant.Uint64Val(v) 60 return !ok || x>>bits != 0 61 } 62 x, ok := constant.Int64Val(v) 63 if x < 0 { 64 x = ^x 65 } 66 return !ok || x>>(bits-1) != 0 67 case t.IsFloat(): 68 switch t.Size() { 69 case 4: 70 f, _ := constant.Float32Val(v) 71 return math.IsInf(float64(f), 0) 72 case 8: 73 f, _ := constant.Float64Val(v) 74 return math.IsInf(f, 0) 75 } 76 case t.IsComplex(): 77 ft := types.FloatForComplex(t) 78 return ConstOverflow(constant.Real(v), ft) || ConstOverflow(constant.Imag(v), ft) 79 } 80 base.Fatalf("ConstOverflow: %v, %v", v, t) 81 panic("unreachable") 82 } 83 84 // IsConstNode reports whether n is a Go language constant (as opposed to a 85 // compile-time constant). 86 // 87 // Expressions derived from nil, like string([]byte(nil)), while they 88 // may be known at compile time, are not Go language constants. 89 func IsConstNode(n Node) bool { 90 return n.Op() == OLITERAL 91 } 92 93 func IsSmallIntConst(n Node) bool { 94 if n.Op() == OLITERAL { 95 v, ok := constant.Int64Val(n.Val()) 96 return ok && int64(int32(v)) == v 97 } 98 return false 99 }