/* ------------------------------------------ * 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 */