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

View as plain text