// Copyright 2015 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package rewritearm64latelower // isARM64addcon reports whether x can be encoded as the immediate value in an ADD or SUB instruction. func isARM64addcon(v int64) bool { /* uimm12 or uimm24? */ if v < 0 { return false } if (v & 0xFFF) == 0 { v >>= 12 } return v <= 0xFFF } // isARM64bitcon reports whether a constant can be encoded into a logical instruction. func isARM64bitcon(x uint64) bool { if x == 1<<64-1 || x == 0 { return false } // determine the period and sign-extend a unit to 64 bits switch { case x != x>>32|x<<32: // period is 64 // nothing to do case x != x>>16|x<<48: // period is 32 x = uint64(int64(int32(x))) case x != x>>8|x<<56: // period is 16 x = uint64(int64(int16(x))) case x != x>>4|x<<60: // period is 8 x = uint64(int64(int8(x))) default: // period is 4 or 2, always true // 0001, 0010, 0100, 1000 -- 0001 rotate // 0011, 0110, 1100, 1001 -- 0011 rotate // 0111, 1011, 1101, 1110 -- 0111 rotate // 0101, 1010 -- 01 rotate, repeat return true } return sequenceOfOnes(x) || sequenceOfOnes(^x) } // sequenceOfOnes tests whether a constant is a sequence of ones in binary, with leading and trailing zeros. func sequenceOfOnes(x uint64) bool { y := x & -x // lowest set bit of x. x is good iff x+y is a power of 2 y += x return (y-1)&y == 0 }