]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: intrinsic for math/bits.Reverse on ARM64
authorKeith Randall <keithr@alum.mit.edu>
Fri, 17 Mar 2017 05:34:38 +0000 (22:34 -0700)
committerKeith Randall <khr@golang.org>
Fri, 17 Mar 2017 18:07:18 +0000 (18:07 +0000)
I don't know that it exists for any other architectures.

Update #18616

Change-Id: Idfe5dee251764d32787915889ec0be4bebc5be24
Reviewed-on: https://go-review.googlesource.com/38323
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/ssa/gen/ARM64.rules
src/cmd/compile/internal/ssa/gen/genericOps.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/rewriteARM64.go

index bd04ff536e64677de3450057187b4ea6c990c364..773aecbddc9c86bc3f58ace6e329d8428e6132e7 100644 (file)
@@ -2749,6 +2749,34 @@ func init() {
                },
                sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS)
        // LeadingZeros is handled because it trivially calls Len.
+       addF("math/bits", "Reverse64",
+               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpBitRev64, Types[TINT], args[0])
+               },
+               sys.ARM64)
+       addF("math/bits", "Reverse32",
+               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpBitRev32, Types[TINT], args[0])
+               },
+               sys.ARM64)
+       addF("math/bits", "Reverse16",
+               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpBitRev16, Types[TINT], args[0])
+               },
+               sys.ARM64)
+       addF("math/bits", "Reverse8",
+               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpBitRev8, Types[TINT], args[0])
+               },
+               sys.ARM64)
+       addF("math/bits", "Reverse",
+               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+                       if s.config.IntSize == 4 {
+                               return s.newValue1(ssa.OpBitRev32, Types[TINT], args[0])
+                       }
+                       return s.newValue1(ssa.OpBitRev64, Types[TINT], args[0])
+               },
+               sys.ARM64)
 
        /******** sync/atomic ********/
 
index 9331ab154b61945b3f5f85ae2a922ec7d6e1eb94..0654024ebc497332a8627f08c0d125af6fb52f21 100644 (file)
 (Bswap64 x) -> (REV x)
 (Bswap32 x) -> (REVW x)
 
+(BitRev64 x) -> (RBIT x)
+(BitRev32 x) -> (RBITW x)
+(BitRev16 x) -> (SRLconst [48] (RBIT <config.fe.TypeUInt64()> x))
+(BitRev8 x) -> (SRLconst [56] (RBIT <config.fe.TypeUInt64()> x))
+
 // boolean ops -- booleans are represented with 0=false, 1=true
 (AndB x y) -> (AND x y)
 (OrB x y) -> (OR x y)
index b4c2a015e165868d99b9ebfddbc7b9c6e29756b5..a5ac62829ee09e5fb28ebecdf0959858ec758391 100644 (file)
@@ -244,6 +244,11 @@ var genericOps = []opData{
        {name: "Bswap32", argLength: 1}, // Swap bytes
        {name: "Bswap64", argLength: 1}, // Swap bytes
 
+       {name: "BitRev8", argLength: 1},  // Reverse the bits in arg[0]
+       {name: "BitRev16", argLength: 1}, // Reverse the bits in arg[0]
+       {name: "BitRev32", argLength: 1}, // Reverse the bits in arg[0]
+       {name: "BitRev64", argLength: 1}, // Reverse the bits in arg[0]
+
        {name: "Sqrt", argLength: 1}, // sqrt(arg0), float64 only
 
        // Data movement, max argument length for Phi is indefinite so just pick
index 146c52ed9f83f48d8f7e0cf508d6afecf590d027..f5729243baa50520acffe10df3b357556a85eea0 100644 (file)
@@ -1767,6 +1767,10 @@ const (
        OpBitLen64
        OpBswap32
        OpBswap64
+       OpBitRev8
+       OpBitRev16
+       OpBitRev32
+       OpBitRev64
        OpSqrt
        OpPhi
        OpCopy
@@ -21481,6 +21485,26 @@ var opcodeTable = [...]opInfo{
                argLen:  1,
                generic: true,
        },
+       {
+               name:    "BitRev8",
+               argLen:  1,
+               generic: true,
+       },
+       {
+               name:    "BitRev16",
+               argLen:  1,
+               generic: true,
+       },
+       {
+               name:    "BitRev32",
+               argLen:  1,
+               generic: true,
+       },
+       {
+               name:    "BitRev64",
+               argLen:  1,
+               generic: true,
+       },
        {
                name:    "Sqrt",
                argLen:  1,
index 10a3589598c17a771cbeb4b77cec6ab090c421be..cb48e664fe259c55937ec004e88750676613512a 100644 (file)
@@ -252,6 +252,14 @@ func rewriteValueARM64(v *Value, config *Config) bool {
                return rewriteValueARM64_OpAvg64u(v, config)
        case OpBitLen64:
                return rewriteValueARM64_OpBitLen64(v, config)
+       case OpBitRev16:
+               return rewriteValueARM64_OpBitRev16(v, config)
+       case OpBitRev32:
+               return rewriteValueARM64_OpBitRev32(v, config)
+       case OpBitRev64:
+               return rewriteValueARM64_OpBitRev64(v, config)
+       case OpBitRev8:
+               return rewriteValueARM64_OpBitRev8(v, config)
        case OpBswap32:
                return rewriteValueARM64_OpBswap32(v, config)
        case OpBswap64:
@@ -9714,6 +9722,64 @@ func rewriteValueARM64_OpBitLen64(v *Value, config *Config) bool {
                return true
        }
 }
+func rewriteValueARM64_OpBitRev16(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (BitRev16 x)
+       // cond:
+       // result: (SRLconst [48] (RBIT <config.fe.TypeUInt64()> x))
+       for {
+               x := v.Args[0]
+               v.reset(OpARM64SRLconst)
+               v.AuxInt = 48
+               v0 := b.NewValue0(v.Pos, OpARM64RBIT, config.fe.TypeUInt64())
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+}
+func rewriteValueARM64_OpBitRev32(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (BitRev32 x)
+       // cond:
+       // result: (RBITW x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARM64RBITW)
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM64_OpBitRev64(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (BitRev64 x)
+       // cond:
+       // result: (RBIT x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARM64RBIT)
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM64_OpBitRev8(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (BitRev8 x)
+       // cond:
+       // result: (SRLconst [56] (RBIT <config.fe.TypeUInt64()> x))
+       for {
+               x := v.Args[0]
+               v.reset(OpARM64SRLconst)
+               v.AuxInt = 56
+               v0 := b.NewValue0(v.Pos, OpARM64RBIT, config.fe.TypeUInt64())
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+}
 func rewriteValueARM64_OpBswap32(v *Value, config *Config) bool {
        b := v.Block
        _ = b