Source file src/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  				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  

View as plain text