Source file src/cmd/compile/internal/ssarewrite/rewriteamd64/amd64_helpers.go

     1  // Copyright 2015 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 rewriteamd64
     6  
     7  import (
     8  	"cmd/compile/internal/base"
     9  	"cmd/compile/internal/ssa"
    10  	"cmd/compile/internal/ssa/ssaop"
    11  	"cmd/compile/internal/types"
    12  )
    13  
    14  // amd64CapAVXShift caps an AMD64 AVX vector shift amount c so that over-shifts
    15  // always result in 0.
    16  //
    17  // These instructions have room for an 8-bit immediate and any value larger than
    18  // the element width will result in 0 or -1 (for an arithmetic right shift).
    19  // Thus, we simply cap this at 255.
    20  func amd64CapAVXShift(auxInt int64) uint8 {
    21  	u := ssa.AuxIntToUint64(auxInt)
    22  	if u > 255 {
    23  		return 255
    24  	}
    25  	return uint8(u)
    26  }
    27  
    28  // flagify rewrites v which is (X ...) to (Select0 (Xflags ...)).
    29  func flagify(v *ssa.Value) bool {
    30  	var flagVersion ssaop.Op
    31  	switch v.Op {
    32  	case ssaop.OpAMD64ADDQconst:
    33  		flagVersion = ssaop.OpAMD64ADDQconstflags
    34  	case ssaop.OpAMD64ADDLconst:
    35  		flagVersion = ssaop.OpAMD64ADDLconstflags
    36  	default:
    37  		base.Fatalf("can't flagify op %s", v.Op)
    38  	}
    39  	inner := v.CopyInto(v.Block)
    40  	inner.Op = flagVersion
    41  	inner.Type = types.NewTuple(v.Type, types.TypeFlags)
    42  	v.Reset(ssaop.OpSelect0)
    43  	v.AddArg(inner)
    44  	return true
    45  }
    46  
    47  // sequentialAddresses reports true if it can prove that x + n == y
    48  func sequentialAddresses(x, y *ssa.Value, n int64) bool {
    49  	if x == y && n == 0 {
    50  		return true
    51  	}
    52  	if x.Op == ssaop.Op386ADDL && y.Op == ssaop.Op386LEAL1 && y.AuxInt == n && y.Aux == nil &&
    53  		(x.Args[0] == y.Args[0] && x.Args[1] == y.Args[1] ||
    54  			x.Args[0] == y.Args[1] && x.Args[1] == y.Args[0]) {
    55  		return true
    56  	}
    57  	if x.Op == ssaop.Op386LEAL1 && y.Op == ssaop.Op386LEAL1 && y.AuxInt == x.AuxInt+n && x.Aux == y.Aux &&
    58  		(x.Args[0] == y.Args[0] && x.Args[1] == y.Args[1] ||
    59  			x.Args[0] == y.Args[1] && x.Args[1] == y.Args[0]) {
    60  		return true
    61  	}
    62  	if x.Op == ssaop.OpAMD64ADDQ && y.Op == ssaop.OpAMD64LEAQ1 && y.AuxInt == n && y.Aux == nil &&
    63  		(x.Args[0] == y.Args[0] && x.Args[1] == y.Args[1] ||
    64  			x.Args[0] == y.Args[1] && x.Args[1] == y.Args[0]) {
    65  		return true
    66  	}
    67  	if x.Op == ssaop.OpAMD64LEAQ1 && y.Op == ssaop.OpAMD64LEAQ1 && y.AuxInt == x.AuxInt+n && x.Aux == y.Aux &&
    68  		(x.Args[0] == y.Args[0] && x.Args[1] == y.Args[1] ||
    69  			x.Args[0] == y.Args[1] && x.Args[1] == y.Args[0]) {
    70  		return true
    71  	}
    72  	return false
    73  }
    74  
    75  // validVal reports whether the value can be used
    76  // as an argument to makeValAndOff.
    77  func validVal(val int64) bool {
    78  	return val == int64(int32(val))
    79  }
    80  

View as plain text