/**
 * \file
 *
 * \brief Compiler abstraction layer: GCC specifics
 *
 * - Compiler:           GNU GCC for AVR32
 * - Supported devices:  All devices
 * - AppNote:
 *
 * \author               Atmel Corporation: http://www.atmel.com \n
 *                       Support and FAQ: http://support.atmel.no/
 *
 * \page License
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * 3. The name of Atmel may not be used to endorse or promote products derived
 * from this software without specific prior written permission.
 *
 * 4. This software may only be redistributed and used in connection with an
 * Atmel AVR product.
 *
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 */
#ifndef COMPILER_GCC_H_INCLUDED
#define COMPILER_GCC_H_INCLUDED

/**
 * \brief The function does not return
 *
 * This function annotation gives a hint to the compiler that the
 * function being annotated does not return. This may give the
 * compiler some more room for optimizations.
 */
#define __noreturn __attribute__((noreturn))
/**
 * \brief The return value must be checked
 *
 * This annotation may cause the compiler to warn if someone calls the
 * annotated function without checking its return value.
 */
#define __must_check __attribute__((warn_unused_result))
/**
 * \brief Pack structure contents
 *
 * This annotation causes the compiler to omit any padding from a
 * struct normally inserted to keep its fields aligned for maximum
 * efficiency.
 */
#define __packed __attribute__((packed))
/**
 * \brief Place a function or data object in a specific section
 *
 * This annotation instructs the compiler to place the annotated
 * function or data object in the section named \a name.
 */
#define __section(name) __attribute__((section(name)))
/**
 * \brief Mark a function or data object as weak.
 *
 * This annotation instructs the compiler to emit a weak symbol for
 * the annotated function or data object. This allows other
 * compilation units to override this definition by providing a strong
 * symbol.
 */
#define __weak __attribute__((weak))
/**
 * \brief Mark a function or data object as being used.
 *
 * The compiler will normally warn about functions or variables
 * defined as static but not referenced anywhere. By annotating them
 * with __used, the compiler will shut up and emit the symbol. This is
 * useful when a symbol is only referenced by inline assembly code,
 * for example.
 */
#define __used __attribute__((used))
/**
 * \brief The function should always be inlined.
 *
 * This annotation instructs the compiler to ignore its inlining
 * heuristics and inline the function no matter how big it thinks it
 * becomes.
 */
#define __always_inline inline __attribute__((always_inline))
/**
 * \brief The function takes a printf-like format string.
 *
 * This annotation may cause the compiler to emit a warning if the
 * format string doesn't match the parameters given.
 */
#define __printf_format(fmt_index, first_arg_index)	\
	__attribute__((format(printf, fmt_index, first_arg_index)))

/**
 * \brief The expression \a exp is likely to be true
 */
#define likely(exp)	__builtin_expect(!!(exp), 1)
/**
 * \brief The expression \a exp is unlikely to be true
 */
#define unlikely(exp)	__builtin_expect(!!(exp), 0)

/**
 * \brief Determine if an expression evaluates to a constant value.
 *
 * \param exp Any expression
 *
 * \return true if \a exp is constant, false otherwise.
 */
#define is_constant(exp) __builtin_constant_p(exp)

/**
 * \brief Optimization barrier.
 *
 * This macro forces the compiler to reload any variables from memory.
 * Local variables are left alone, unless they had their address taken
 * at some point.
 */
#define barrier()	asm volatile("" ::: "memory")

/**
 * \brief Count Leading Zeroes
 *
 * Count the number of 0 bits in \a x before the first 1 bit, starting
 * at the most significant bit.
 */
#define count_leading_zeroes(x) __builtin_clz(x)

/**
 * \brief Get the lowest of two values.
 * \param x An integer
 * \param y Another integer
 * \return The numerically lowest value of \a x and \a y.
 */
#define min(x,y)				\
	({					\
		typeof(x) __x = (x);		\
		typeof(y) __y = (y);		\
		__x < __y ? __x : __y;		\
	})

/**
 * \brief Get the highest of two values.
 * \param x An integer
 * \param y Another integer
 * \return The numerically highest value of \a x and \a y.
 */
#define max(x,y)				\
	({					\
		typeof(x) __x = (x);		\
		typeof(y) __y = (y);		\
		__x > __y ? __x : __y;		\
	})

/* Pull in arch-specific definitions and overrides */
#include <arch/compiler-gcc.h>

#endif /* COMPILER_GCC_H_INCLUDED */
