#ifndef __CR_COMPILER_H__
#define __CR_COMPILER_H__

/*
 * Various definitions for success build,
 * picked from various places, mostly from
 * the linux kernel.
 */

#define ARRAY_SIZE(x)		(sizeof(x) / sizeof((x)[0]))
#define NELEMS_AS_ARRAY(x,y)	(sizeof(x) / sizeof((y)[0]))
#define BUILD_BUG_ON(condition)	((void)sizeof(char[1 - 2*!!(condition)]))

#define ASSIGN_TYPED(a, b)	do { (a) = (typeof(a))(b); } while (0)
#define ASSIGN_MEMBER(a, b, m)	do { ASSIGN_TYPED((a)->m, (b)->m); } while (0)

#define __stringify_1(x...)	#x
#define __stringify(x...)	__stringify_1(x)

#define NORETURN		__attribute__((__noreturn__))
#define __packed		__attribute__((__packed__))
#define __used			__attribute__((__used__))
#define __maybe_unused		__attribute__((unused))
#define __always_unused		__attribute__((unused))
#define __must_check		__attribute__((__warn_unused_result__))

#define __section(S)		__attribute__ ((__section__(#S)))

#ifndef __always_inline
# define __always_inline	inline __attribute__((always_inline))
#endif

#define likely(x)		__builtin_expect(!!(x), 1)
#define unlikely(x)		__builtin_expect(!!(x), 0)

#ifndef always_inline
# define always_inline		__always_inline
#endif

#ifndef noinline
# define noinline		__attribute__((noinline))
#endif

#define __aligned(x)		__attribute__((aligned(x)))

/*
 * Macro to define stack alignment. 
 * aarch64 requires stack to be aligned to 16 bytes.
 */
#define __stack_aligned__	__attribute__((aligned(16)))

#ifndef offsetof
# define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif

#define barrier()		asm volatile("" ::: "memory")

#define container_of(ptr, type, member) ({			\
	const typeof( ((type *)0)->member ) *__mptr = (ptr);	\
	(type *)( (char *)__mptr - offsetof(type,member) );})

#ifndef FIELD_SIZEOF
# define FIELD_SIZEOF(t, f)	(sizeof(((t*)0)->f))
#endif

#define __round_mask(x, y)	((__typeof__(x))((y) - 1))
#define round_up(x, y)		((((x) - 1) | __round_mask(x, y)) + 1)
#define round_down(x, y)	((x) & ~__round_mask(x, y))
#define DIV_ROUND_UP(n,d)	(((n) + (d) - 1) / (d))
#define ALIGN(x, a)		(((x) + (a) - 1) & ~((a) - 1))

#define min(x, y) ({				\
	typeof(x) _min1 = (x);			\
	typeof(y) _min2 = (y);			\
	(void) (&_min1 == &_min2);		\
	_min1 < _min2 ? _min1 : _min2; })

#define max(x, y) ({				\
	typeof(x) _max1 = (x);			\
	typeof(y) _max2 = (y);			\
	(void) (&_max1 == &_max2);		\
	_max1 > _max2 ? _max1 : _max2; })

#define min_t(type, x, y) ({			\
	type __min1 = (x);			\
	type __min2 = (y);			\
	__min1 < __min2 ? __min1: __min2; })

#define max_t(type, x, y) ({			\
	type __max1 = (x);			\
	type __max2 = (y);			\
	__max1 > __max2 ? __max1: __max2; })

#define SWAP(x, y)				\
	do {					\
		typeof(x) ____val = x;		\
		x = y;				\
		y = ____val;			\
	} while (0)

#define is_log2(v)		(((v) & ((v) - 1)) == 0)

/*
 * Use "__ignore_value" to avoid a warning when using a function declared with
 * gcc's warn_unused_result attribute, but for which you really do want to
 * ignore the result.  Traditionally, people have used a "(void)" cast to
 * indicate that a function's return value is deliberately unused.  However,
 * if the function is declared with __attribute__((warn_unused_result)),
 * gcc issues a warning even with the cast.
 *
 * Caution: most of the time, you really should heed gcc's warning, and
 * check the return value.  However, in those exceptional cases in which
 * you're sure you know what you're doing, use this function.
 *
 * Normally casting an expression to void discards its value, but GCC
 * versions 3.4 and newer have __attribute__ ((__warn_unused_result__))
 * which may cause unwanted diagnostics in that case.  Use __typeof__
 * and __extension__ to work around the problem, if the workaround is
 * known to be needed.
 * Written by Jim Meyering, Eric Blake and Pádraig Brady.
 * (See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425 for the details)
 */
#if 3 < __GNUC__ + (4 <= __GNUC_MINOR__)
# define __ignore_value(x)	({ __typeof__ (x) __x = (x); (void) __x; })
#else
# define __ignore_value(x) ((void) (x))
#endif

#endif /* __CR_COMPILER_H__ */
