/**
 * \file
 *
 * \brief Compiler abstraction layer
 *
 * - Compiler:           IAR EWAVR32 and GNU GCC for AVR32
 * - Supported devices:  All devices
 * - AppNote:
 *
 * \sa compiler/gcc.h
 * \sa compiler/sparse.h
 *
 * \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_H_INCLUDED
#define COMPILER_H_INCLUDED

/* The "sparse" syntax checker defines __CHECKER__ */
#if defined(__CHECKER__)
# include <compiler/sparse.h>
#elif defined(__GNUC__)
# include <compiler/gcc.h>
#elif defined(__ICCAVR32__)
# include <compiler/iar.h>
#endif

#ifndef __bitwise
# define __bitwise
#endif

#ifndef __virtual
# define __virtual
#endif

#ifndef __physical
# define __physical
#endif

#ifndef __force
# define __force
#endif

#ifndef __noreturn
# define __noreturn
#endif

#ifndef __must_check
# define __must_check
#endif

#ifndef __packed
# define __packed
# warning Compiler does not support __packed -- expect breakage!
#endif

#ifndef __section
# define __section(name)
# warning Compiler does not support __section -- expect breakage!
#endif

#ifndef __weak
# define __weak
# warning Compiler does not support __weak -- expect breakage!
#endif

#ifndef __used
# define __used
#endif

#ifndef __always_inline
# define __always_inline inline
#endif

#ifndef __printf_format
# define __printf_format(fmt_index, first_arg_index)
#endif

#ifndef likely
# define likely(exp)	(exp)
#endif

#ifndef unlikely
# define unlikely(exp)	(exp)
#endif

#ifndef barrier
# define barrier()	do { } while (0)
# warning Compiler does not support barrier() -- expect breakage!
#endif

#ifndef is_constant
# define is_constant(x) (0)
#endif

#ifndef count_leading_zeroes
# include <stdint.h>

static inline unsigned int count_leading_zeroes(uint32_t x)
{
	unsigned int bit = 31;

	if (x & 0xffff0000) {
		bit -= 16;
		x >>= 16;
	}
	if (x & 0xff00) {
		bit -= 8;
		x >>= 8;
	}
	if (x & 0xf0) {
		bit -= 4;
		x >>= 4;
	}
	if (x & 0xc) {
		bit -= 2;
		x >>= 2;
	}
	if (x & 2)
		bit--;

	return bit;
}
# define count_leading_zeroes(x)  count_leading_zeroes(x)
#endif

#ifndef bit_reverse
static inline unsigned long bit_reverse(unsigned long word)
{
# if BITS_PER_LONG == 32
	/* swap odd and even bits */
	word = ((word >> 1) & 0x55555555) | ((word & 0x55555555) << 1);
	/* swap consecutive pairs */
	word = ((word >> 2) & 0x33333333) | ((word & 0x33333333) << 2);
	/* swap nibbles */
	word = ((word >> 4) & 0x0F0F0F0F) | ((word & 0x0F0F0F0F) << 4);
	/* swap bytes */
	word = ((word >> 8) & 0x00FF00FF) | ((word & 0x00FF00FF) << 8);
	/* swap 2-byte long pairs */
	word = ( word >> 16             ) | ( word               << 16);
# else
#  error Could not implement bit_reverse for this architecture
# endif
}
# define bit_reverse(word)	bit_reverse(word)
#endif

#ifndef min
# define min(a, b)	((a) < (b) ? (a) : (b))
# warning Compiler did not define min() -- using dangerous default definition
#endif

#ifndef max
# define max(a, b)	((a) < (b) ? (b) : (a))
# warning Compiler did not define max() -- using dangerous default definition
#endif

#endif /* COMPILER_H_INCLUDED */
