/* ------------------------------------------ | |
* Copyright (c) 2016, Synopsys, Inc. All rights reserved. | |
* 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) Neither the name of the Synopsys, Inc., nor the names of its contributors may | |
* be used to endorse or promote products derived from this software without | |
* specific prior written permission. | |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. | |
* | |
* \version 2016.05 | |
* \date 2014-06-12 | |
* \author Wayne Ren(Wei.Ren@synopsys.com) | |
--------------------------------------------- */ | |
/** | |
* \file | |
* \ingroup ARC_HAL_BUILTIN | |
* \brief header file of builtin and helper functions | |
* | |
* The Metaware toolchain and the GNU toolchain are supported. The details please go to see the file. | |
*/ | |
/** | |
* \addtogroup ARC_HAL_BUILTIN | |
* @{ | |
*/ | |
#ifndef _ARC_HAL_BUILTIN_H_ | |
#define _ARC_HAL_BUILTIN_H_ | |
#include "inc/embARC_toolchain.h" | |
#ifdef __cplusplus | |
extern "C" { | |
#endif | |
#if defined (__MW__) /* Metaware toolchain */ | |
#define _arc_nop _nop /*!< no operation, generate a nop instruction produces a single NOP instruction in the compiled code */ | |
#define _arc_brk _brk /*!< generate a brk instruction */ | |
#define _arc_clri _clri /*!< generate a clri instruction */ | |
#define _arc_seti(c) _seti(c) /*!< generate a seti instruction */ | |
#define _arc_core_write(regno, val) _core_write(val, regno) /*!< write core register */ | |
#define _arc_core_read(regno) _core_read(regno) /*!< read core register */ | |
#define _arc_lr_reg(aux) _lr(aux) /*!< read auxiliary register */ | |
#define _arc_sr_reg(aux, val) _sr(val, aux) /*!< write auxiliary register */ | |
#define _arc_sleep(a) _sleep(a) /*!< generate a sleep instruction */ | |
#define _arc_flag(a) _flag(a) /*!< generate a flag instruction */ | |
#define _arc_kflag(a) | |
#define _arc_sync _sync /*!< generate a sync instruction */ | |
/* | |
* !< _arc_usually (expr) evaluates expression expr and | |
* informs the compiler that the value is usually true. | |
*/ | |
#define _arc_usually(a) _Usually((a)) | |
/* | |
* !< _arc_rarely (expr) evaluates expression expr and | |
* informs the compiler that the value is rarely true. | |
*/ | |
#define _arc_rarely(a) _Rarely((a)) | |
#if 0 | |
/** | |
* \brief Reverses the byte order of the 16-bit operand, | |
* reversing the endianness of the value. | |
* Not for ARC HS family | |
*/ | |
#define _arc_swap16(a) _swap16(a) | |
/** | |
* \brief Reverses the byte order of the 32-bit operand, | |
* reversing the endianness of the value. | |
* Not for ARC HS family | |
*/ | |
#define _arc_swap32(a) _swap32(a) | |
#else | |
Inline uint32_t _arc_swap32(uint32_t val) | |
{ | |
register uint32_t v; | |
__asm__ volatile("swape %0, %1" :"=r"(v): "r"(val)); | |
return v; | |
} | |
Inline uint16_t _arc_swap16(uint32_t val) | |
{ | |
register uint32_t temp; | |
register uint32_t v; | |
__asm__ volatile("swape %0, %1" :"=r"(temp): "r"(val)); | |
__asm__ volatile("lsr16 %0, %1" :"=r"(v): "r"(temp)); | |
return (unsigned short)v; | |
} | |
#endif | |
/** | |
* \brief Each call to _swi() generates one | |
* software interrupt instruction (SWI) for processors | |
* to support the SWI instruction. | |
*/ | |
#define _arc_swi _swi | |
/* \todo add more builtin functions of metaware tool */ | |
#elif defined (__GNU__) /* GNU toolchain */ | |
#define _arc_nop __builtin_arc_nop | |
#define _arc_brk __builtin_arc_brk | |
#define _arc_seti(c) __builtin_arc_seti(c) | |
#define _arc_core_write(regno, val) __builtin_arc_core_write(regno,val) | |
#define _arc_core_read(regno) __builtin_arc_core_read(regno) | |
#define _arc_flag(a) __builtin_arc_flag(a) | |
#define _arc_kflag(a) __builtin_arc_kflag(a) | |
#define _arc_lr_reg(aux) __builtin_arc_lr(aux) | |
/* don't uncomment this now */ | |
//#define _arc_sr_reg(aux, val) __builtin_arc_sr(aux, val) | |
#define _arc_sleep(a) __builtin_arc_sleep(a) | |
//#define _arc_sync __builtin_arc_sync | |
/** | |
* \brief _arc_usually (expr) evaluates expression expr and | |
* informs the compiler that the value is usually true. | |
*/ | |
#define _arc_usually(a) __builtin_expect((int)(a), 1) | |
/** | |
* \brief _arc_rarely (expr) evaluates expression expr and | |
* informs the compiler that the value is rarely true. | |
*/ | |
#define _arc_rarely(a) __builtin_expect((int)(a), 0) | |
/** | |
* \brief Each call to _swi() generates one | |
* software interrupt instruction (SWI) for processors | |
* to support the SWI instruction. | |
*/ | |
#define _arc_swi __builtin_arc_swi | |
Inline uint32_t _arc_clri(void) | |
{ | |
register uint32_t v; | |
__asm__ volatile("clri %0" :"=r"(v)); | |
return v; | |
} | |
/* \todo add more builtin functions of gnu tool */ | |
Inline uint32_t _arc_swap32(uint32_t val) | |
{ | |
register uint32_t v; | |
__asm__ volatile("swape %0, %1" :"=r"(v): "r"(val)); | |
return v; | |
} | |
Inline uint16_t _arc_swap16(uint32_t val) | |
{ | |
register uint32_t temp; | |
register uint32_t v; | |
__asm__ volatile("swape %0, %1" :"=r"(temp): "r"(val)); | |
__asm__ volatile("lsr16 %0, %1" :"=r"(v): "r"(temp)); | |
return (unsigned short)v; | |
} | |
Inline void _arc_sync(void) | |
{ | |
__asm__ volatile("sync"); | |
} | |
/** | |
* \note Following is a workaround for arc gcc | |
* built-in function __builtin_arc_sr. | |
* But it is wrong in GCC arc-4.8-R3-rc3 and shouldn't be used. | |
*/ | |
/* | |
* The auxiliary register address is specified as a long immediate operand by caller. | |
* e.g. | |
* write_aux_reg(0x69, some_val); | |
* This generates the tightest code. | |
*/ | |
#define write_aux_reg(reg_imm, val) \ | |
({ \ | |
Asm( \ | |
" sr %0, [%1] \n" \ | |
: \ | |
: "ir"(val), "r"(reg_imm)); \ | |
}) | |
#define _arc_sr_reg(aux, val) write_aux_reg(aux, val) | |
#endif | |
/* \todo add more helper functions here, such as memory operation */ | |
#define _arc_aux_read(aux) _arc_lr_reg(aux) | |
#define _arc_aux_write(aux, val) _arc_sr_reg(aux, val) | |
/** | |
* \name cache related helper function | |
* @{ | |
*/ | |
/** | |
* \brief read memory and bypass the cache | |
* \param[in] ptr memory address | |
* \return value in the memory | |
*/ | |
Inline uint32_t _arc_read_uncached_32(void *ptr) | |
{ | |
uint32_t __ret; | |
Asm("ld.di %0, [%1]": "=r"(__ret): "r"(ptr)); | |
return __ret; | |
} | |
/** | |
* \brief write memory and bypass the cache | |
* \param[in] ptr memory address | |
* \param[in] data vaule to be written | |
*/ | |
Inline void _arc_write_uncached_32(void *ptr, uint32_t data) | |
{ | |
Asm("st.di %0, [%1]":: "r"(data), "r"(ptr)); | |
} | |
/** | |
* \brief read memory with cache | |
* \param[in] ptr memory address | |
* \returns value in the memory | |
*/ | |
Inline uint32_t _arc_read_cached_32(void *ptr) | |
{ | |
uint32_t __ret; | |
Asm("ld %0, [%1]": "=r"(__ret): "r"(ptr)); | |
return __ret; | |
} | |
/** | |
* \brief read memory with cache | |
* \param[in] ptr memory address | |
* \param[in] data vaule to be written | |
* \return description | |
*/ | |
Inline void _arc_write_cached_32(void *ptr, uint32_t data) | |
{ | |
Asm("st %0, [%1]":: "r"(data), "r"(ptr)); | |
} | |
/** | |
* \brief go to main function with proper arguments | |
* \param argc argument count | |
* \param argv argument content array | |
* \retval return value of main function | |
*/ | |
Inline int32_t _arc_goto_main(int argc, char **argv) | |
{ | |
int __ret; | |
__asm__ volatile( | |
"mov %%r0, %1\n" | |
"mov %%r1, %2\n" | |
"push_s %%blink\n" | |
"jl main\n" | |
"pop_s %%blink\n" | |
"mov %0, %%r0" | |
:"=r"(__ret): "r"(argc), "r"(argv)); | |
return (int)__ret; | |
} | |
#ifdef __cplusplus | |
} | |
#endif | |
#if defined(LIB_SECURESHIELD) && defined(LIB_SECURESHIELD_OVERRIDES) && (SECURESHIELD_VERSION == 1) | |
#define OVERRIDE_ARC_HAL_BUILTIN_H | |
#include "secureshield_overrides.h" | |
#endif | |
/** @} */ | |
#endif /* _ARC_HAL_BUILTIN_H_ */ | |
/** @} */ |