summaryrefslogtreecommitdiffstats
path: root/src/cmd/compile/internal/ssa/softfloat.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/ssa/softfloat.go')
-rw-r--r--src/cmd/compile/internal/ssa/softfloat.go80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/ssa/softfloat.go b/src/cmd/compile/internal/ssa/softfloat.go
new file mode 100644
index 0000000..351f824
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/softfloat.go
@@ -0,0 +1,80 @@
+// 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 (
+ "cmd/compile/internal/types"
+ "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() {
+ f.unCache(v)
+ 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(auxTo32F(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
+ } else if (v.Op == OpStore || v.Op == OpZero || v.Op == OpMove) && v.Aux.(*types.Type).IsFloat() {
+ switch size := v.Aux.(*types.Type).Size(); size {
+ case 4:
+ v.Aux = f.Config.Types.UInt32
+ case 8:
+ v.Aux = f.Config.Types.UInt64
+ newInt64 = true
+ default:
+ v.Fatalf("bad float type with size %d", size)
+ }
+ }
+ }
+ }
+
+ if newInt64 && f.Config.RegSize == 4 {
+ // On 32bit arch, decompose Uint64 introduced in the switch above.
+ decomposeBuiltIn(f)
+ applyRewrite(f, rewriteBlockdec64, rewriteValuedec64, removeDeadValues)
+ }
+
+}