blob: b065269236686f4f8ffa481838179afd2f1dcbe7 [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-07-15
* \author Wayne Ren(Wei.Ren@synopsys.com)
--------------------------------------------- */
/**
* \file
* \ingroup ARC_HAL_MISC
* \brief common macro definitions for assembly file
*/
/** @cond ARC_HAL_ASM_COMMON */
#ifndef _ARC_HAL_ASM_COMMON_H_
#define _ARC_HAL_ASM_COMMON_H_
#include "embARC_BSP_config.h"
#include "arc_feature_config.h"
/* Note on the LD/ST addr modes with addr reg wback
*
* LD.a same as LD.aw
*
* LD.a reg1, [reg2, x] => Pre Incr
* Eff Addr for load = [reg2 + x]
*
* LD.ab reg1, [reg2, x] => Post Incr
* Eff Addr for load = [reg2]
*/
#if defined(__GNU__)
.macro PUSH reg
st.a \reg, [sp, -4]
.endm
.macro PUSHAX aux
lr r10, [\aux]
PUSH r10
.endm
.macro POP reg
ld.ab \reg, [sp, 4]
.endm
.macro POPAX aux
POP r10
sr r10, [\aux]
.endm
#else
.macro PUSH, reg
st.a reg, [sp, -4]
.endm
.macro PUSHAX, aux
lr r10, [aux]
PUSH r10
.endm
.macro POP, reg
ld.ab reg, [sp, 4]
.endm
.macro POPAX, aux
POP r10
sr r10, [aux]
.endm
#endif
/*--------------------------------------------------------------
* Helpers to save/restore callee-saved regs:
* used by several macros below
*-------------------------------------------------------------*/
.macro SAVE_CALLEE_REGS
PUSH r13
PUSH r14
PUSH r15
#ifndef ARC_FEATURE_RF16
PUSH r16
PUSH r17
PUSH r18
PUSH r19
PUSH r20
PUSH r21
PUSH r22
PUSH r23
PUSH r24
PUSH r25
#endif
.endm
.macro RESTORE_CALLEE_REGS
#ifndef ARC_FEATURE_RF16
POP r25
POP r24
POP r23
POP r22
POP r21
POP r20
POP r19
POP r18
POP r17
POP r16
#endif
POP r15
POP r14
POP r13
.endm
.macro CLEAR_CALLEE_REGS
#ifndef ARC_FEATURE_RF16
mov r25, 0
mov r24, 0
mov r23, 0
mov r22, 0
mov r21, 0
mov r20, 0
mov r19, 0
mov r18, 0
mov r17, 0
mov r16, 0
#endif
mov r15, 0
mov r14, 0
mov r13, 0
.endm
.macro CLEAR_SCRATCH_REGS
mov r1, 0
mov r2, 0
mov r3, 0
mov r4, 0
mov r5, 0
mov r6, 0
mov r7, 0
mov r8, 0
mov r9, 0
mov r10, 0
mov r11, 0
mov r12, 0
mov fp, 0
mov r29, 0
mov r30, 0
.endm
.macro SAVE_LP_REGS
PUSH r60
PUSHAX AUX_LP_START
PUSHAX AUX_LP_END
.endm
.macro RESTORE_LP_REGS
POPAX AUX_LP_END
POPAX AUX_LP_START
POP r10
/* must not use the LP_COUNT register(r60) as the destination of multi-cycle instruction */
mov r60, r10
.endm
.macro SAVE_R0_TO_R12
PUSH r0
PUSH r1
PUSH r2
PUSH r3
#ifndef ARC_FEATURE_RF16
PUSH r4
PUSH r5
PUSH r6
PUSH r7
PUSH r8
PUSH r9
#endif
PUSH r10
PUSH r11
PUSH r12
.endm
.macro RESTORE_R0_TO_R12
POP r12
POP r11
POP r10
#ifndef ARC_FEATURE_RF16
POP r9
POP r8
POP r7
POP r6
POP r5
POP r4
#endif
POP r3
POP r2
POP r1
POP r0
.endm
.macro SAVE_CODE_DENSITY
PUSHAX AUX_JLI_BASE
PUSHAX AUX_LDI_BASE
PUSHAX AUX_EI_BASE
.endm
.macro RESTORE_CODE_DENSITY
POPAX AUX_EI_BASE
POPAX AUX_LDI_BASE
POPAX AUX_JLI_BASE
.endm
/* todo: check the contents of NON_SCRATCH_REGS in debug */
.macro SAVE_NONSCRATCH_REGS
/* r0-r12 are saved by caller function */
PUSH gp
PUSH fp
PUSH blink
SAVE_CALLEE_REGS
.endm
.macro RESTORE_NONSCRATCH_REGS
RESTORE_CALLEE_REGS
POP blink
POP fp
POP gp
.endm
.macro SAVE_FIQ_EXC_REGS
#ifndef ARC_FEATURE_RGF_BANKED_REGS
SAVE_R0_TO_R12
PUSH gp
PUSH fp
PUSH r30 /* general purpose */
PUSH blink
#else
#if ARC_FEATURE_RGF_BANKED_REGS != 4 && ARC_FEATURE_RGF_BANKED_REGS != 8 && \
ARC_FEATURE_RGF_BANKED_REGS != 16 && ARC_FEATURE_RGF_BANKED_REGS != 32
#error "unsupported ARC_FEATURE_RGF_BANKED_REGS"
#endif
#if ARC_FEATURE_RGF_BANKED_REGS == 4 || ARC_FEATURE_BANKED_REGS == 8 || \
ARC_FEATURE_RGF_BANKED_REGS == 16
PUSH r4
PUSH r5
PUSH r6
PUSH r7
PUSH r8
PUSH r9
#endif
#if ARC_FEATURE_RGF_BANKED_REGS == 4 || ARC_FEATURE_BANKED_REGS == 8
PUSH r10
PUSH r11
#endif
#if ARC_FEATURE_RGF_BANKED_REGS == 4
PUSH r12
#endif
#if ARC_FEATURE_RGF_BANKED_REGS == 4 || ARC_FEATURE_BANKED_REGS == 8
PUSH gp
PUSH fp
PUSH r30 /* general purpose */
PUSH blink
#endif
#endif /* #ifndef ARC_FEATURE_RGF_BANKED_REGS */
#ifdef ARC_FEATURE_CODE_DENSITY
SAVE_CODE_DENSITY
#endif
SAVE_LP_REGS
.endm
.macro RESTORE_FIQ_EXC_REGS
RESTORE_LP_REGS
#ifdef ARC_FEATURE_CODE_DENSITY
RESTORE_CODE_DENSITY
#endif
#ifndef ARC_FEATURE_RGF_BANKED_REGS
POP blink
POP r30
POP fp
POP gp
RESTORE_R0_TO_R12
#else
#if ARC_FEATURE_RGF_BANKED_REGS != 4 && ARC_FEATURE_RGF_BANKED_REGS != 8 && \
ARC_FEATURE_RGF_BANKED_REGS != 16 && ARC_FEATURE_RGF_BANKED_REGS != 32
#error "unsupported ARC_FEATURE_RGF_BANKED_REGS"
#endif
#if ARC_FEATURE_RGF_BANKED_REGS == 4 || ARC_FEATURE_BANKED_REGS == 8
POP blink
POP r30
POP fp
POP gp
#endif
#if ARC_FEATURE_RGF_BANKED_REGS == 4
POP r12
#endif
#if ARC_FEATURE_RGF_BANKED_REGS == 4 || ARC_FEATURE_BANKED_REGS == 8
POP r11
POP r10
#endif
#if ARC_FEATURE_RGF_BANKED_REGS == 4 || ARC_FEATURE_BANKED_REGS == 8 || \
ARC_FEATURE_RGF_BANKED_REGS == 16
POP r9
POP r8
POP r7
POP r6
POP r5
POP r4
#endif
#endif /* #ifndef ARC_FEATURE_RGF_BANKED_REGS */
.endm
/* normal interrupt prologue, pc, status and r0-r11 are saved by hardware */
.macro INTERRUPT_PROLOGUE
PUSH r12
PUSH gp
PUSH fp
PUSH ilink
PUSH r30
sub sp, sp, 4 /* skip bta */
.endm
/* normal interrupt epilogue, pc, status and r0-r11 are restored by hardware */
.macro INTERRUPT_EPILOGUE
add sp, sp, 4 /* skip bta */
POP r30
POP ilink
POP fp
POP gp
POP r12
.endm
#if SECURESHIELD_VERSION == 2
/* exception prologue, create the same frame of interrupt manually */
.macro EXCEPTION_PROLOGUE
st.as r10, [sp, -6] /* save r10 first, free up a register*/
PUSHAX AUX_ERSTATUS
sub sp, sp, 4 /* slot for SEC_STAT */
PUSHAX AUX_ERRET
PUSH blink
PUSH r11
sub sp, sp, 4 /* r10 is pushed before */
#ifndef ARC_FEATURE_RF16
PUSH r9
PUSH r8
PUSH r7
PUSH r6
PUSH r5
PUSH r4
#endif
PUSH r3
PUSH r2
PUSH r1
PUSH r0
#ifdef ARC_FEATURE_CODE_DENSITY
SAVE_CODE_DENSITY
#endif
SAVE_LP_REGS
PUSH r12
PUSH gp
PUSH fp
PUSH ilink
PUSH r30
PUSHAX AUX_ERBTA
.endm
/* exception epilogue, restore the same frame of interrupt manually */
.macro EXCEPTION_EPILOGUE
POPAX AUX_ERBTA
POP r30
POP ilink
POP fp
POP gp
POP r12
RESTORE_LP_REGS
#ifdef ARC_FEATURE_CODE_DENSITY
RESTORE_CODE_DENSITY
#endif
POP r0
POP r1
POP r2
POP r3
#ifndef ARC_FEATURE_RF16
POP r4
POP r5
POP r6
POP r7
POP r8
POP r9
#endif
add sp, sp, 4 /* r10 will be popped finally */
POP r11
POP blink
POPAX AUX_ERRET
add sp, sp, 4 /* slot for SEC_STAT */
POPAX AUX_ERSTATUS
ld.as r10, [sp, -6] /* restore r10 */
.endm
#else /* normal version */
/* exception prologue, create the same frame of interrupt manually */
.macro EXCEPTION_PROLOGUE
#ifdef ARC_FEATURE_CODE_DENSITY
st.as r10, [sp, -11] /* save r10 first, free up a register*/
#else
st.as r10, [sp, -8]
#endif
PUSHAX AUX_ERSTATUS
PUSHAX AUX_ERRET
#ifdef ARC_FEATURE_CODE_DENSITY
SAVE_CODE_DENSITY
#endif
SAVE_LP_REGS
PUSH blink
PUSH r11
sub sp, sp, 4 /* r10 is pushed before */
#ifndef ARC_FEATURE_RF16
PUSH r9
PUSH r8
PUSH r7
PUSH r6
PUSH r5
PUSH r4
#endif
PUSH r3
PUSH r2
PUSH r1
PUSH r0
PUSH r12
PUSH gp
PUSH fp
PUSH ilink
PUSH r30
PUSHAX AUX_ERBTA
.endm
/* exception epilogue, restore the same frame of interrupt manually */
.macro EXCEPTION_EPILOGUE
POPAX AUX_ERBTA
POP r30
POP ilink
POP fp
POP gp
POP r12
POP r0
POP r1
POP r2
POP r3
#ifndef ARC_FEATURE_RF16
POP r4
POP r5
POP r6
POP r7
POP r8
POP r9
#endif
add sp, sp, 4 /* r10 will be popped finally */
POP r11
POP blink
RESTORE_LP_REGS
#ifdef ARC_FEATURE_CODE_DENSITY
RESTORE_CODE_DENSITY
#endif
POPAX AUX_ERRET
POPAX AUX_ERSTATUS
#ifdef ARC_FEATURE_CODE_DENSITY
ld.as r10, [sp, -11] /* restore r10 */
#else
ld.as r10, [sp, -8]
#endif
.endm
#endif /* SECURESHIELD_VERSION == 2 */
#endif /* _ARC_HAL_ASM_COMMON_H */
/** @endcond */