blob: bbf257aade2ea776555111006269130ce72bc682 [file] [log] [blame]
/* ------------------------------------------
* 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_ */
/** @} */