/**************************************************************************//**
* @file     cmsis_compiler.h
* @brief    CMSIS compiler generic header file
* @version  V5.1.0
* @date     09. October 2018
******************************************************************************/

/*
 * Copyright (c) 2009-2018 Arm Limited. All rights reserved.
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the License); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef __CMSIS_COMPILER_H
#define __CMSIS_COMPILER_H

#include <stdint.h>

/*
 * Arm Compiler 4/5
 */
#if   defined( __CC_ARM )
    #include "cmsis_armcc.h"


/*
 * Arm Compiler 6.6 LTM (armclang)
 */
#elif defined( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) && ( __ARMCC_VERSION < 6100100 )
    #include "cmsis_armclang_ltm.h"

/*
 * Arm Compiler above 6.10.1 (armclang)
 */
#elif defined( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6100100 )
    #include "cmsis_armclang.h"


/*
 * GNU Compiler
 */
#elif defined( __GNUC__ )
    #include "cmsis_gcc.h"


/*
 * IAR Compiler
 */
#elif defined( __ICCARM__ )
    #include <cmsis_iccarm.h>


/*
 * TI Arm Compiler
 */
#elif defined( __TI_ARM__ )
    #include <cmsis_ccs.h>

    #ifndef   __ASM
        #define __ASM                   __asm
    #endif
    #ifndef   __INLINE
        #define __INLINE                inline
    #endif
    #ifndef   __STATIC_INLINE
        #define __STATIC_INLINE         static inline
    #endif
    #ifndef   __STATIC_FORCEINLINE
        #define __STATIC_FORCEINLINE    __STATIC_INLINE
    #endif
    #ifndef   __NO_RETURN
        #define __NO_RETURN             __attribute__( ( noreturn ) )
    #endif
    #ifndef   __USED
        #define __USED                  __attribute__( ( used ) )
    #endif
    #ifndef   __WEAK
        #define __WEAK                  __attribute__( ( weak ) )
    #endif
    #ifndef   __PACKED
        #define __PACKED                __attribute__( ( packed ) )
    #endif
    #ifndef   __PACKED_STRUCT
        #define __PACKED_STRUCT         struct __attribute__( ( packed ) )
    #endif
    #ifndef   __PACKED_UNION
        #define __PACKED_UNION          union __attribute__( ( packed ) )
    #endif
    #ifndef   __UNALIGNED_UINT32 /* deprecated */
        struct __attribute__( ( packed ) ) T_UINT32
        {
            uint32_t v;
        };
        #define __UNALIGNED_UINT32( x )    ( ( ( struct T_UINT32 * ) ( x ) )->v )
    #endif
    #ifndef   __UNALIGNED_UINT16_WRITE
    __PACKED_STRUCT T_UINT16_WRITE {
        uint16_t v;
    };
        #define __UNALIGNED_UINT16_WRITE( addr, val )    ( void ) ( ( ( ( struct T_UINT16_WRITE * ) ( void * ) ( addr ) )->v ) = ( val ) )
    #endif
    #ifndef   __UNALIGNED_UINT16_READ
    __PACKED_STRUCT T_UINT16_READ {
        uint16_t v;
    };
        #define __UNALIGNED_UINT16_READ( addr )    ( ( ( const struct T_UINT16_READ * ) ( const void * ) ( addr ) )->v )
    #endif
    #ifndef   __UNALIGNED_UINT32_WRITE
    __PACKED_STRUCT T_UINT32_WRITE {
        uint32_t v;
    };
        #define __UNALIGNED_UINT32_WRITE( addr, val )    ( void ) ( ( ( ( struct T_UINT32_WRITE * ) ( void * ) ( addr ) )->v ) = ( val ) )
    #endif
    #ifndef   __UNALIGNED_UINT32_READ
    __PACKED_STRUCT T_UINT32_READ {
        uint32_t v;
    };
        #define __UNALIGNED_UINT32_READ( addr )    ( ( ( const struct T_UINT32_READ * ) ( const void * ) ( addr ) )->v )
    #endif
    #ifndef   __ALIGNED
        #define __ALIGNED( x )                     __attribute__( ( aligned( x ) ) )
    #endif
    #ifndef   __RESTRICT
        #define __RESTRICT    __restrict
    #endif
    #ifndef   __COMPILER_BARRIER
        #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
        #define __COMPILER_BARRIER()    ( void ) 0
    #endif


/*
 * TASKING Compiler
 */
#elif defined( __TASKING__ )

/*
 * The CMSIS functions have been implemented as intrinsics in the compiler.
 * Please use "carm -?i" to get an up to date list of all intrinsics,
 * Including the CMSIS ones.
 */

    #ifndef   __ASM
        #define __ASM                   __asm
    #endif
    #ifndef   __INLINE
        #define __INLINE                inline
    #endif
    #ifndef   __STATIC_INLINE
        #define __STATIC_INLINE         static inline
    #endif
    #ifndef   __STATIC_FORCEINLINE
        #define __STATIC_FORCEINLINE    __STATIC_INLINE
    #endif
    #ifndef   __NO_RETURN
        #define __NO_RETURN             __attribute__( ( noreturn ) )
    #endif
    #ifndef   __USED
        #define __USED                  __attribute__( ( used ) )
    #endif
    #ifndef   __WEAK
        #define __WEAK                  __attribute__( ( weak ) )
    #endif
    #ifndef   __PACKED
        #define __PACKED                __packed__
    #endif
    #ifndef   __PACKED_STRUCT
        #define __PACKED_STRUCT         struct __packed__
    #endif
    #ifndef   __PACKED_UNION
        #define __PACKED_UNION          union __packed__
    #endif
    #ifndef   __UNALIGNED_UINT32 /* deprecated */
        struct __packed__ T_UINT32
        {
            uint32_t v;
        };
        #define __UNALIGNED_UINT32( x )    ( ( ( struct T_UINT32 * ) ( x ) )->v )
    #endif
    #ifndef   __UNALIGNED_UINT16_WRITE
    __PACKED_STRUCT T_UINT16_WRITE {
        uint16_t v;
    };
        #define __UNALIGNED_UINT16_WRITE( addr, val )    ( void ) ( ( ( ( struct T_UINT16_WRITE * ) ( void * ) ( addr ) )->v ) = ( val ) )
    #endif
    #ifndef   __UNALIGNED_UINT16_READ
    __PACKED_STRUCT T_UINT16_READ {
        uint16_t v;
    };
        #define __UNALIGNED_UINT16_READ( addr )    ( ( ( const struct T_UINT16_READ * ) ( const void * ) ( addr ) )->v )
    #endif
    #ifndef   __UNALIGNED_UINT32_WRITE
    __PACKED_STRUCT T_UINT32_WRITE {
        uint32_t v;
    };
        #define __UNALIGNED_UINT32_WRITE( addr, val )    ( void ) ( ( ( ( struct T_UINT32_WRITE * ) ( void * ) ( addr ) )->v ) = ( val ) )
    #endif
    #ifndef   __UNALIGNED_UINT32_READ
    __PACKED_STRUCT T_UINT32_READ {
        uint32_t v;
    };
        #define __UNALIGNED_UINT32_READ( addr )    ( ( ( const struct T_UINT32_READ * ) ( const void * ) ( addr ) )->v )
    #endif
    #ifndef   __ALIGNED
        #define __ALIGNED( x )                     __align( x )
    #endif
    #ifndef   __RESTRICT
        #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
        #define __RESTRICT
    #endif
    #ifndef   __COMPILER_BARRIER
        #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
        #define __COMPILER_BARRIER()    ( void ) 0
    #endif


/*
 * COSMIC Compiler
 */
#elif defined( __CSMC__ )
    #include <cmsis_csm.h>

    #ifndef   __ASM
        #define __ASM                   _asm
    #endif
    #ifndef   __INLINE
        #define __INLINE                inline
    #endif
    #ifndef   __STATIC_INLINE
        #define __STATIC_INLINE         static inline
    #endif
    #ifndef   __STATIC_FORCEINLINE
        #define __STATIC_FORCEINLINE    __STATIC_INLINE
    #endif
    #ifndef   __NO_RETURN
        /* NO RETURN is automatically detected hence no warning here */
        #define __NO_RETURN
    #endif
    #ifndef   __USED
        #warning No compiler specific solution for __USED. __USED is ignored.
        #define __USED
    #endif
    #ifndef   __WEAK
        #define __WEAK             __weak
    #endif
    #ifndef   __PACKED
        #define __PACKED           @packed
    #endif
    #ifndef   __PACKED_STRUCT
        #define __PACKED_STRUCT    @packed struct
    #endif
    #ifndef   __PACKED_UNION
        #define __PACKED_UNION     @packed union
    #endif
    #ifndef   __UNALIGNED_UINT32 /* deprecated */
        @packed struct T_UINT32
        {
            uint32_t v;
        };
        #define __UNALIGNED_UINT32( x )    ( ( ( struct T_UINT32 * ) ( x ) )->v )
    #endif
    #ifndef   __UNALIGNED_UINT16_WRITE
    __PACKED_STRUCT T_UINT16_WRITE {
        uint16_t v;
    };
        #define __UNALIGNED_UINT16_WRITE( addr, val )    ( void ) ( ( ( ( struct T_UINT16_WRITE * ) ( void * ) ( addr ) )->v ) = ( val ) )
    #endif
    #ifndef   __UNALIGNED_UINT16_READ
    __PACKED_STRUCT T_UINT16_READ {
        uint16_t v;
    };
        #define __UNALIGNED_UINT16_READ( addr )    ( ( ( const struct T_UINT16_READ * ) ( const void * ) ( addr ) )->v )
    #endif
    #ifndef   __UNALIGNED_UINT32_WRITE
    __PACKED_STRUCT T_UINT32_WRITE {
        uint32_t v;
    };
        #define __UNALIGNED_UINT32_WRITE( addr, val )    ( void ) ( ( ( ( struct T_UINT32_WRITE * ) ( void * ) ( addr ) )->v ) = ( val ) )
    #endif
    #ifndef   __UNALIGNED_UINT32_READ
    __PACKED_STRUCT T_UINT32_READ {
        uint32_t v;
    };
        #define __UNALIGNED_UINT32_READ( addr )    ( ( ( const struct T_UINT32_READ * ) ( const void * ) ( addr ) )->v )
    #endif
    #ifndef   __ALIGNED
        #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
        #define __ALIGNED( x )
    #endif
    #ifndef   __RESTRICT
        #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
        #define __RESTRICT
    #endif
    #ifndef   __COMPILER_BARRIER
        #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
        #define __COMPILER_BARRIER()    ( void ) 0
    #endif


#else /* if   defined( __CC_ARM ) */
    #error Unknown compiler.
#endif /* if   defined( __CC_ARM ) */


#endif /* __CMSIS_COMPILER_H */
