github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/compile/internal/ssa/softfloat.go (about)

     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  	"github.com/gagliardetto/golang-go/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  }