blob: b49421ac4ff18225730e14a0859a345900bbff79 [file] [log] [blame]
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (c) 2016, Linaro Limited
*/
#include <asm.S>
#if defined(CFG_TA_GPROF_SUPPORT) || defined(CFG_FTRACE_SUPPORT)
/*
* Convert return address to call site address by subtracting the size of the
* mcount call instruction (blx __gnu_mcount_nc).
*/
.macro mcount_adj_pc rd, rn
bic \rd, \rn, #1 /* Clear thumb bit if present */
sub \rd, \rd, #4
.endm
/*
* With the -pg option, GCC (4.4+) inserts a call to __gnu_mcount_nc into
* every function prologue.
* The caller of the instrumented function can be determined from the lr value
* stored on the top of the stack. The callee, i.e. the instrumented function
* itself, is determined from the current value of lr. Then we call:
* void __mcount_internal(void *frompc, void *selfpc);
*/
FUNC __gnu_mcount_nc, :
stmdb sp!, {r0-r3, lr}
#if defined(CFG_TA_GPROF_SUPPORT) && !defined(__KERNEL__)
ldr r0, [sp, #20] /* lr of instrumented func */
mcount_adj_pc r0, r0
mcount_adj_pc r1, lr /* instrumented func */
bl __mcount_internal
#endif
#ifdef CFG_FTRACE_SUPPORT
/* Get instrumented function's pc value */
ldr r0, [sp, #16]
mcount_adj_pc r0, r0
/* Get instrumented function's lr address pointer */
sub r1, fp, #4
bl ftrace_enter
#endif
ldmia sp!, {r0-r3, ip, lr}
bx ip
END_FUNC __gnu_mcount_nc
#ifdef CFG_FTRACE_SUPPORT
FUNC __ftrace_return, :
/* save return value regs */
stmdb sp!, {r0-r3}
/* get return address of parent func */
bl ftrace_return
mov lr, r0
/* restore return value regs */
ldmia sp!, {r0-r3}
bx lr
END_FUNC __ftrace_return
#endif
#endif /* CFG_TA_GPROF_SUPPORT || CFG_FTRACE_SUPPORT */