1// Copyright 2017 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
5package ssa
6
7import (
8	"cmd/compile/internal/types"
9	"math"
10)
11
12func softfloat(f *Func) {
13	if !f.Config.SoftFloat {
14		return
15	}
16	newInt64 := false
17
18	for _, b := range f.Blocks {
19		for _, v := range b.Values {
20			if v.Type.IsFloat() {
21				f.unCache(v)
22				switch v.Op {
23				case OpPhi, OpLoad, OpArg:
24					if v.Type.Size() == 4 {
25						v.Type = f.Config.Types.UInt32
26					} else {
27						v.Type = f.Config.Types.UInt64
28					}
29				case OpConst32F:
30					v.Op = OpConst32
31					v.Type = f.Config.Types.UInt32
32					v.AuxInt = int64(int32(math.Float32bits(auxTo32F(v.AuxInt))))
33				case OpConst64F:
34					v.Op = OpConst64
35					v.Type = f.Config.Types.UInt64
36				case OpNeg32F:
37					arg0 := v.Args[0]
38					v.reset(OpXor32)
39					v.Type = f.Config.Types.UInt32
40					v.AddArg(arg0)
41					mask := v.Block.NewValue0(v.Pos, OpConst32, v.Type)
42					mask.AuxInt = -0x80000000
43					v.AddArg(mask)
44				case OpNeg64F:
45					arg0 := v.Args[0]
46					v.reset(OpXor64)
47					v.Type = f.Config.Types.UInt64
48					v.AddArg(arg0)
49					mask := v.Block.NewValue0(v.Pos, OpConst64, v.Type)
50					mask.AuxInt = -0x8000000000000000
51					v.AddArg(mask)
52				case OpRound32F:
53					v.Op = OpCopy
54					v.Type = f.Config.Types.UInt32
55				case OpRound64F:
56					v.Op = OpCopy
57					v.Type = f.Config.Types.UInt64
58				}
59				newInt64 = newInt64 || v.Type.Size() == 8
60			} else if (v.Op == OpStore || v.Op == OpZero || v.Op == OpMove) && v.Aux.(*types.Type).IsFloat() {
61				switch size := v.Aux.(*types.Type).Size(); size {
62				case 4:
63					v.Aux = f.Config.Types.UInt32
64				case 8:
65					v.Aux = f.Config.Types.UInt64
66					newInt64 = true
67				default:
68					v.Fatalf("bad float type with size %d", size)
69				}
70			}
71		}
72	}
73
74	if newInt64 && f.Config.RegSize == 4 {
75		// On 32bit arch, decompose Uint64 introduced in the switch above.
76		decomposeBuiltIn(f)
77		applyRewrite(f, rewriteBlockdec64, rewriteValuedec64, removeDeadValues)
78	}
79
80}
81