...

Source file src/pkg/cmd/compile/internal/ssa/softfloat.go

     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	
     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					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	

View as plain text