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				switch v.Op {
22				case OpPhi, OpLoad, OpArg:
23					if v.Type.Size() == 4 {
24						v.Type = f.Config.Types.UInt32
25					} else {
26						v.Type = f.Config.Types.UInt64
27					}
28				case OpConst32F:
29					v.Op = OpConst32
30					v.Type = f.Config.Types.UInt32
31					v.AuxInt = int64(int32(math.Float32bits(auxTo32F(v.AuxInt))))
32				case OpConst64F:
33					v.Op = OpConst64
34					v.Type = f.Config.Types.UInt64
35				case OpNeg32F:
36					arg0 := v.Args[0]
37					v.reset(OpXor32)
38					v.Type = f.Config.Types.UInt32
39					v.AddArg(arg0)
40					mask := v.Block.NewValue0(v.Pos, OpConst32, v.Type)
41					mask.AuxInt = -0x80000000
42					v.AddArg(mask)
43				case OpNeg64F:
44					arg0 := v.Args[0]
45					v.reset(OpXor64)
46					v.Type = f.Config.Types.UInt64
47					v.AddArg(arg0)
48					mask := v.Block.NewValue0(v.Pos, OpConst64, v.Type)
49					mask.AuxInt = -0x8000000000000000
50					v.AddArg(mask)
51				case OpRound32F:
52					v.Op = OpCopy
53					v.Type = f.Config.Types.UInt32
54				case OpRound64F:
55					v.Op = OpCopy
56					v.Type = f.Config.Types.UInt64
57				}
58				newInt64 = newInt64 || v.Type.Size() == 8
59			} else if (v.Op == OpStore || v.Op == OpZero || v.Op == OpMove) && v.Aux.(*types.Type).IsFloat() {
60				switch size := v.Aux.(*types.Type).Size(); size {
61				case 4:
62					v.Aux = f.Config.Types.UInt32
63				case 8:
64					v.Aux = f.Config.Types.UInt64
65				default:
66					v.Fatalf("bad float type with size %d", size)
67				}
68			}
69		}
70	}
71
72	if newInt64 && f.Config.RegSize == 4 {
73		// On 32bit arch, decompose Uint64 introduced in the switch above.
74		decomposeBuiltIn(f)
75		applyRewrite(f, rewriteBlockdec64, rewriteValuedec64)
76	}
77
78}
79