blob: d2a22c1403ab6cd6f04446a839c7bf9f5a4c8c08 [file] [log] [blame]
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// The rotate(A, B) builtin left-shifts corresponding to the usual OpenCL shift
// modulo rules. These rules state that A is left-shifted by the log2(N) least
// significant bits in B when viewed as an unsigned integer value. Thus we don't
// have to worry about signed shift amounts, and can perform the computation in
// unsigned types.
_CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE __clc_rotate(__CLC_GENTYPE x,
__CLC_GENTYPE n) {
__CLC_U_GENTYPE x_as_u = __CLC_AS_U_GENTYPE(x);
__CLC_U_GENTYPE mask = (__CLC_U_GENTYPE)(__CLC_GENSIZE - 1);
__CLC_U_GENTYPE lshift_amt = __CLC_AS_U_GENTYPE(n) & mask;
__CLC_U_GENTYPE rshift_amt =
(((__CLC_U_GENTYPE)__CLC_GENSIZE - lshift_amt) & mask);
__CLC_U_GENTYPE result = (x_as_u << lshift_amt) | (x_as_u >> rshift_amt);
return __CLC_AS_GENTYPE(result);
}