// Copyright 2017 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 ssa import "math" func softfloat(f *Func) { if !f.Config.SoftFloat { return } newInt64 := false for _, b := range f.Blocks { for _, v := range b.Values { if v.Type.IsFloat() { switch v.Op { case OpPhi, OpLoad, OpArg: if v.Type.Size() == 4 { v.Type = f.Config.Types.UInt32 } else { v.Type = f.Config.Types.UInt64 } case OpConst32F: v.Op = OpConst32 v.Type = f.Config.Types.UInt32 v.AuxInt = int64(int32(math.Float32bits(i2f32(v.AuxInt)))) case OpConst64F: v.Op = OpConst64 v.Type = f.Config.Types.UInt64 case OpNeg32F: arg0 := v.Args[0] v.reset(OpXor32) v.Type = f.Config.Types.UInt32 v.AddArg(arg0) mask := v.Block.NewValue0(v.Pos, OpConst32, v.Type) mask.AuxInt = -0x80000000 v.AddArg(mask) case OpNeg64F: arg0 := v.Args[0] v.reset(OpXor64) v.Type = f.Config.Types.UInt64 v.AddArg(arg0) mask := v.Block.NewValue0(v.Pos, OpConst64, v.Type) mask.AuxInt = -0x8000000000000000 v.AddArg(mask) case OpRound32F: v.Op = OpCopy v.Type = f.Config.Types.UInt32 case OpRound64F: v.Op = OpCopy v.Type = f.Config.Types.UInt64 } newInt64 = newInt64 || v.Type.Size() == 8 } } } if newInt64 && f.Config.RegSize == 4 { // On 32bit arch, decompose Uint64 introduced in the switch above. decomposeBuiltIn(f) applyRewrite(f, rewriteBlockdec64, rewriteValuedec64) } }