Source file src/cmd/compile/internal/ssarewrite/rewritearm64latelower/arm64latelower_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 rewritearm64latelower 6 7 // isARM64addcon reports whether x can be encoded as the immediate value in an ADD or SUB instruction. 8 func isARM64addcon(v int64) bool { 9 /* uimm12 or uimm24? */ 10 if v < 0 { 11 return false 12 } 13 if (v & 0xFFF) == 0 { 14 v >>= 12 15 } 16 return v <= 0xFFF 17 } 18 19 // isARM64bitcon reports whether a constant can be encoded into a logical instruction. 20 func isARM64bitcon(x uint64) bool { 21 if x == 1<<64-1 || x == 0 { 22 return false 23 } 24 // determine the period and sign-extend a unit to 64 bits 25 switch { 26 case x != x>>32|x<<32: 27 // period is 64 28 // nothing to do 29 case x != x>>16|x<<48: 30 // period is 32 31 x = uint64(int64(int32(x))) 32 case x != x>>8|x<<56: 33 // period is 16 34 x = uint64(int64(int16(x))) 35 case x != x>>4|x<<60: 36 // period is 8 37 x = uint64(int64(int8(x))) 38 default: 39 // period is 4 or 2, always true 40 // 0001, 0010, 0100, 1000 -- 0001 rotate 41 // 0011, 0110, 1100, 1001 -- 0011 rotate 42 // 0111, 1011, 1101, 1110 -- 0111 rotate 43 // 0101, 1010 -- 01 rotate, repeat 44 return true 45 } 46 return sequenceOfOnes(x) || sequenceOfOnes(^x) 47 } 48 49 // sequenceOfOnes tests whether a constant is a sequence of ones in binary, with leading and trailing zeros. 50 func sequenceOfOnes(x uint64) bool { 51 y := x & -x // lowest set bit of x. x is good iff x+y is a power of 2 52 y += x 53 return (y-1)&y == 0 54 } 55