302 lines
8.3 KiB
C
302 lines
8.3 KiB
C
/* ------------------------------------------
|
|
* 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_ */
|
|
/** @} */
|