root/arch/xtensa/kernel/mcount.S
/*
 * arch/xtensa/kernel/mcount.S
 *
 * Xtensa specific mcount support
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2013 Tensilica Inc.
 */

#include <linux/linkage.h>
#include <asm/asmmacro.h>
#include <asm/ftrace.h>

/*
 * Entry condition:
 *
 *   a2:        a0 of the caller in windowed ABI
 *   a10:       a0 of the caller in call0 ABI
 *
 * In call0 ABI the function _mcount is called with the special ABI:
 * its argument is in a10 and all the usual argument registers (a2 - a7)
 * must be preserved in addition to callee-saved a12 - a15.
 */

ENTRY(_mcount)
#if defined(__XTENSA_WINDOWED_ABI__)
        abi_entry_default

        movi    a4, ftrace_trace_function
        l32i    a4, a4, 0
        movi    a3, ftrace_stub
        bne     a3, a4, 1f
        abi_ret_default

1:      xor     a7, a2, a1
        movi    a3, 0x3fffffff
        and     a7, a7, a3
        xor     a7, a7, a1

        xor     a6, a0, a1
        and     a6, a6, a3
        xor     a6, a6, a1
        addi    a6, a6, -MCOUNT_INSN_SIZE
        callx4  a4

        abi_ret_default
#elif defined(__XTENSA_CALL0_ABI__)
        abi_entry_default

        movi    a9, ftrace_trace_function
        l32i    a9, a9, 0
        movi    a11, ftrace_stub
        bne     a9, a11, 1f
        abi_ret_default

1:      abi_entry(28)
        s32i    a0, sp, 0
        s32i    a2, sp, 4
        s32i    a3, sp, 8
        s32i    a4, sp, 12
        s32i    a5, sp, 16
        s32i    a6, sp, 20
        s32i    a7, sp, 24
        addi    a2, a10, -MCOUNT_INSN_SIZE
        callx0  a9
        l32i    a0, sp, 0
        l32i    a2, sp, 4
        l32i    a3, sp, 8
        l32i    a4, sp, 12
        l32i    a5, sp, 16
        l32i    a6, sp, 20
        l32i    a7, sp, 24
        abi_ret(28)
#else
#error Unsupported Xtensa ABI
#endif
ENDPROC(_mcount)
EXPORT_SYMBOL(_mcount)

ENTRY(ftrace_stub)
        abi_entry_default
        abi_ret_default
ENDPROC(ftrace_stub)