cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

bitops.h (3762B)


      1/* SPDX-License-Identifier: GPL-2.0-only */
      2/*
      3 * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
      4 */
      5
      6#ifndef _ASM_BITOPS_H
      7#define _ASM_BITOPS_H
      8
      9#ifndef _LINUX_BITOPS_H
     10#error only <linux/bitops.h> can be included directly
     11#endif
     12
     13#ifndef __ASSEMBLY__
     14
     15#include <linux/types.h>
     16#include <linux/compiler.h>
     17
     18#ifdef CONFIG_ISA_ARCOMPACT
     19
     20/*
     21 * Count the number of zeros, starting from MSB
     22 * Helper for fls( ) friends
     23 * This is a pure count, so (1-32) or (0-31) doesn't apply
     24 * It could be 0 to 32, based on num of 0's in there
     25 * clz(0x8000_0000) = 0, clz(0xFFFF_FFFF)=0, clz(0) = 32, clz(1) = 31
     26 */
     27static inline __attribute__ ((const)) int clz(unsigned int x)
     28{
     29	unsigned int res;
     30
     31	__asm__ __volatile__(
     32	"	norm.f  %0, %1		\n"
     33	"	mov.n   %0, 0		\n"
     34	"	add.p   %0, %0, 1	\n"
     35	: "=r"(res)
     36	: "r"(x)
     37	: "cc");
     38
     39	return res;
     40}
     41
     42static inline int constant_fls(unsigned int x)
     43{
     44	int r = 32;
     45
     46	if (!x)
     47		return 0;
     48	if (!(x & 0xffff0000u)) {
     49		x <<= 16;
     50		r -= 16;
     51	}
     52	if (!(x & 0xff000000u)) {
     53		x <<= 8;
     54		r -= 8;
     55	}
     56	if (!(x & 0xf0000000u)) {
     57		x <<= 4;
     58		r -= 4;
     59	}
     60	if (!(x & 0xc0000000u)) {
     61		x <<= 2;
     62		r -= 2;
     63	}
     64	if (!(x & 0x80000000u))
     65		r -= 1;
     66	return r;
     67}
     68
     69/*
     70 * fls = Find Last Set in word
     71 * @result: [1-32]
     72 * fls(1) = 1, fls(0x80000000) = 32, fls(0) = 0
     73 */
     74static inline __attribute__ ((const)) int fls(unsigned int x)
     75{
     76	if (__builtin_constant_p(x))
     77	       return constant_fls(x);
     78
     79	return 32 - clz(x);
     80}
     81
     82/*
     83 * __fls: Similar to fls, but zero based (0-31)
     84 */
     85static inline __attribute__ ((const)) int __fls(unsigned long x)
     86{
     87	if (!x)
     88		return 0;
     89	else
     90		return fls(x) - 1;
     91}
     92
     93/*
     94 * ffs = Find First Set in word (LSB to MSB)
     95 * @result: [1-32], 0 if all 0's
     96 */
     97#define ffs(x)	({ unsigned long __t = (x); fls(__t & -__t); })
     98
     99/*
    100 * __ffs: Similar to ffs, but zero based (0-31)
    101 */
    102static inline __attribute__ ((const)) unsigned long __ffs(unsigned long word)
    103{
    104	if (!word)
    105		return word;
    106
    107	return ffs(word) - 1;
    108}
    109
    110#else	/* CONFIG_ISA_ARCV2 */
    111
    112/*
    113 * fls = Find Last Set in word
    114 * @result: [1-32]
    115 * fls(1) = 1, fls(0x80000000) = 32, fls(0) = 0
    116 */
    117static inline __attribute__ ((const)) int fls(unsigned int x)
    118{
    119	int n;
    120
    121	asm volatile(
    122	"	fls.f	%0, %1		\n"  /* 0:31; 0(Z) if src 0 */
    123	"	add.nz	%0, %0, 1	\n"  /* 0:31 -> 1:32 */
    124	: "=r"(n)	/* Early clobber not needed */
    125	: "r"(x)
    126	: "cc");
    127
    128	return n;
    129}
    130
    131/*
    132 * __fls: Similar to fls, but zero based (0-31). Also 0 if no bit set
    133 */
    134static inline __attribute__ ((const)) int __fls(unsigned long x)
    135{
    136	/* FLS insn has exactly same semantics as the API */
    137	return	__builtin_arc_fls(x);
    138}
    139
    140/*
    141 * ffs = Find First Set in word (LSB to MSB)
    142 * @result: [1-32], 0 if all 0's
    143 */
    144static inline __attribute__ ((const)) int ffs(unsigned int x)
    145{
    146	int n;
    147
    148	asm volatile(
    149	"	ffs.f	%0, %1		\n"  /* 0:31; 31(Z) if src 0 */
    150	"	add.nz	%0, %0, 1	\n"  /* 0:31 -> 1:32 */
    151	"	mov.z	%0, 0		\n"  /* 31(Z)-> 0 */
    152	: "=r"(n)	/* Early clobber not needed */
    153	: "r"(x)
    154	: "cc");
    155
    156	return n;
    157}
    158
    159/*
    160 * __ffs: Similar to ffs, but zero based (0-31)
    161 */
    162static inline __attribute__ ((const)) unsigned long __ffs(unsigned long x)
    163{
    164	unsigned long n;
    165
    166	asm volatile(
    167	"	ffs.f	%0, %1		\n"  /* 0:31; 31(Z) if src 0 */
    168	"	mov.z	%0, 0		\n"  /* 31(Z)-> 0 */
    169	: "=r"(n)
    170	: "r"(x)
    171	: "cc");
    172
    173	return n;
    174
    175}
    176
    177#endif	/* CONFIG_ISA_ARCOMPACT */
    178
    179/*
    180 * ffz = Find First Zero in word.
    181 * @return:[0-31], 32 if all 1's
    182 */
    183#define ffz(x)	__ffs(~(x))
    184
    185#include <asm-generic/bitops/hweight.h>
    186#include <asm-generic/bitops/fls64.h>
    187#include <asm-generic/bitops/sched.h>
    188#include <asm-generic/bitops/lock.h>
    189#include <asm-generic/bitops/atomic.h>
    190#include <asm-generic/bitops/non-atomic.h>
    191
    192#include <asm-generic/bitops/le.h>
    193#include <asm-generic/bitops/ext2-atomic-setbit.h>
    194
    195#endif /* !__ASSEMBLY__ */
    196
    197#endif