1
2
3
4
5 package ssa
6
7 import (
8 "cmd/compile/internal/types"
9 "math"
10 )
11
12 func 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
76 decomposeBuiltIn(f)
77 applyRewrite(f, rewriteBlockdec64, rewriteValuedec64, removeDeadValues)
78 }
79
80 }
81
View as plain text