#ifndef ATCA_COMPILER_H_
#define ATCA_COMPILER_H_
#if defined(__clang__)
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define ATCA_UINT16_HOST_TO_LE(x) __builtin_bswap16(x)
#define ATCA_UINT16_LE_TO_HOST(x) __builtin_bswap16(x)
#define ATCA_UINT32_HOST_TO_LE(x) __builtin_bswap32(x)
#define ATCA_UINT32_HOST_TO_BE(x) (x)
#define ATCA_UINT32_BE_TO_HOST(x) (x)
#define ATCA_UINT64_HOST_TO_BE(x) (x)
#define ATCA_UINT64_BE_TO_HOST(x) (x)
#else
#define ATCA_UINT16_HOST_TO_LE(x) (x)
#define ATCA_UINT16_LE_TO_HOST(x) (x)
#define ATCA_UINT32_HOST_TO_LE(x) (x)
#define ATCA_UINT32_HOST_TO_BE(x) __builtin_bswap32(x)
#define ATCA_UINT32_BE_TO_HOST(x) __builtin_bswap32(x)
#define ATCA_UINT64_HOST_TO_BE(x) __builtin_bswap64(x)
#define ATCA_UINT64_BE_TO_HOST(x) __builtin_bswap64(x)
#endif
#elif defined(__GNUC__) || defined(__GNUG__)
#if defined(__AVR32__)
#define ATCA_UINT16_HOST_TO_LE(x) __builtin_bswap_16(x)
#define ATCA_UINT16_LE_TO_HOST(x) __builtin_bswap_16(x)
#define ATCA_UINT32_HOST_TO_LE(x) __builtin_bswap_32(x)
#define ATCA_UINT32_HOST_TO_BE(x) (x)
#define ATCA_UINT32_BE_TO_HOST(x) (x)
#define ATCA_UINT64_HOST_TO_BE(x) (x)
#define ATCA_UINT64_BE_TO_HOST(x) (x)
#define ATCA_NO_PRAGMA_PACK
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define ATCA_UINT16_HOST_TO_LE(x) __builtin_bswap16(x)
#define ATCA_UINT16_LE_TO_HOST(x) __builtin_bswap16(x)
#define ATCA_UINT32_HOST_TO_LE(x) __builtin_bswap32(x)
#define ATCA_UINT32_HOST_TO_BE(x) (x)
#define ATCA_UINT32_BE_TO_HOST(x) (x)
#define ATCA_UINT64_HOST_TO_BE(x) (x)
#define ATCA_UINT64_BE_TO_HOST(x) (x)
#else
#define ATCA_UINT16_HOST_TO_LE(x) (x)
#define ATCA_UINT16_LE_TO_HOST(x) (x)
#define ATCA_UINT32_HOST_TO_LE(x) (x)
#define ATCA_UINT32_HOST_TO_BE(x) __builtin_bswap32(x)
#define ATCA_UINT32_BE_TO_HOST(x) __builtin_bswap32(x)
#define ATCA_UINT64_HOST_TO_BE(x) __builtin_bswap64(x)
#define ATCA_UINT64_BE_TO_HOST(x) __builtin_bswap64(x)
#endif
#elif defined(_MSC_VER)
#include <stdlib.h>
#define ATCA_UINT16_HOST_TO_LE(x) (x)
#define ATCA_UINT16_LE_TO_HOST(x) (x)
#define ATCA_UINT32_HOST_TO_LE(x) (x)
#define ATCA_UINT32_HOST_TO_BE(x) _byteswap_ulong(x)
#define ATCA_UINT32_BE_TO_HOST(x) _byteswap_ulong(x)
#define ATCA_UINT64_HOST_TO_BE(x) _byteswap_uint64(x)
#define ATCA_UINT64_BE_TO_HOST(x) _byteswap_uint64(x)
#define strtok_r strtok_s
#elif defined __CC_ARM
#ifdef __BIG_ENDIAN
#define ATCA_UINT16_HOST_TO_LE(x) ((x >> 8) | ((x & 0xFF) << 8))
#define ATCA_UINT16_LE_TO_HOST(x) ((x >> 8) | ((x & 0xFF) << 8))
#define ATCA_UINT32_HOST_TO_LE(x) __rev(x)
#define ATCA_UINT32_HOST_TO_BE(x) (x)
#define ATCA_UINT32_BE_TO_HOST(x) (x)
#define ATCA_UINT64_HOST_TO_BE(x) (x)
#define ATCA_UINT64_BE_TO_HOST(x) (x)
#else
#define ATCA_UINT16_HOST_TO_LE(x) (x)
#define ATCA_UINT16_LE_TO_HOST(x) (x)
#define ATCA_UINT32_HOST_TO_LE(x) (x)
#define ATCA_UINT32_HOST_TO_BE(x) __rev(x)
#define ATCA_UINT32_BE_TO_HOST(x) __rev(x)
#define ATCA_UINT64_HOST_TO_BE(x) (((uint64_t)__rev((uint32_t)x) << 32) | (uint64_t)__rev((uint32_t)(x >> 32)))
#define ATCA_UINT64_BE_TO_HOST(x) (((uint64_t)__rev((uint32_t)x) << 32) | (uint64_t)__rev((uint32_t)(x >> 32)))
#endif
#elif defined __ICCARM__
#include <intrinsics.h>
#if __LITTLE_ENDIAN__ == 0
#define ATCA_UINT16_HOST_TO_LE(x) __REV16(x)
#define ATCA_UINT16_LE_TO_HOST(x) __REV16(x)
#define ATCA_UINT32_HOST_TO_LE(x) __REV(x)
#define ATCA_UINT32_HOST_TO_BE(x) (x)
#define ATCA_UINT32_BE_TO_HOST(x) (x)
#define ATCA_UINT64_HOST_TO_BE(x) (x)
#define ATCA_UINT64_BE_TO_HOST(x) (x)
#else
#define ATCA_UINT16_HOST_TO_LE(x) (x)
#define ATCA_UINT16_LE_TO_HOST(x) (x)
#define ATCA_UINT32_HOST_TO_LE(x) (x)
#define ATCA_UINT32_HOST_TO_BE(x) __REV(x)
#define ATCA_UINT32_BE_TO_HOST(x) __REV(x)
#define ATCA_UINT64_HOST_TO_BE(x) (((uint64_t)__REV((uint32_t)x) << 32) | (uint64_t)__REV((uint32_t)(x >> 32)))
#define ATCA_UINT64_BE_TO_HOST(x) (((uint64_t)__REV((uint32_t)x) << 32) | (uint64_t)__REV((uint32_t)(x >> 32)))
#endif
#endif
#endif