/*
 * Copyright 2012 Tilera Corporation. All Rights Reserved.
 *
 *   This program is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU General Public License
 *   as published by the Free Software Foundation, version 2.
 *
 *   This program is distributed in the hope that it will be useful, but
 *   WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 *   NON INFRINGEMENT.  See the GNU General Public License for
 *   more details.
 *
 * TILE-Gx specific __mcount support
 */

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

#define REGSIZE 8

	.text
	.global __mcount

	.macro	MCOUNT_SAVE_REGS
	addli	sp, sp, -REGSIZE
	{
	 st     sp, lr
	 addli	r29, sp, - (12 * REGSIZE)
	}
	{
	 addli	sp, sp, - (13 * REGSIZE)
	 st     r29, sp
	}
	addli	r29, r29, REGSIZE
	{ st	r29, r0; addli	r29, r29, REGSIZE }
	{ st	r29, r1; addli	r29, r29, REGSIZE }
	{ st	r29, r2; addli	r29, r29, REGSIZE }
	{ st	r29, r3; addli	r29, r29, REGSIZE }
	{ st	r29, r4; addli	r29, r29, REGSIZE }
	{ st	r29, r5; addli	r29, r29, REGSIZE }
	{ st	r29, r6; addli	r29, r29, REGSIZE }
	{ st	r29, r7; addli	r29, r29, REGSIZE }
	{ st	r29, r8; addli	r29, r29, REGSIZE }
	{ st	r29, r9; addli	r29, r29, REGSIZE }
	{ st	r29, r10; addli	r29, r29, REGSIZE }
	.endm

	.macro	MCOUNT_RESTORE_REGS
	addli	r29, sp, (2 * REGSIZE)
	{ ld	r0, r29; addli	r29, r29, REGSIZE }
	{ ld	r1, r29; addli	r29, r29, REGSIZE }
	{ ld	r2, r29; addli	r29, r29, REGSIZE }
	{ ld	r3, r29; addli	r29, r29, REGSIZE }
	{ ld	r4, r29; addli	r29, r29, REGSIZE }
	{ ld	r5, r29; addli	r29, r29, REGSIZE }
	{ ld	r6, r29; addli	r29, r29, REGSIZE }
	{ ld	r7, r29; addli	r29, r29, REGSIZE }
	{ ld	r8, r29; addli	r29, r29, REGSIZE }
	{ ld	r9, r29; addli	r29, r29, REGSIZE }
	{ ld	r10, r29; addli	lr, sp, (13 * REGSIZE) }
	{ ld	lr, lr;  addli	sp, sp, (14 * REGSIZE) }
	.endm

	.macro  RETURN_BACK
	{ move	r12, lr; move	lr, r10 }
	jrp	r12
	.endm

#ifdef CONFIG_DYNAMIC_FTRACE

	.align	64
STD_ENTRY(__mcount)
__mcount:
	j	ftrace_stub
STD_ENDPROC(__mcount)

	.align	64
STD_ENTRY(ftrace_caller)
	MCOUNT_SAVE_REGS

	/* arg1: self return address */
	/* arg2: parent's return address */
	/* arg3: ftrace_ops */
	/* arg4: regs (but make it NULL) */
	{ move	r0, lr;  moveli        r2, hw2_last(function_trace_op) }
	{ move	r1, r10; shl16insli    r2, r2, hw1(function_trace_op) }
	{ movei	r3, 0;   shl16insli    r2, r2, hw0(function_trace_op) }
	ld	r2,r2

	.global	ftrace_call
ftrace_call:
	/*
	 * a placeholder for the call to a real tracing function, i.e.
	 * ftrace_trace_function()
	 */
	nop

#ifdef CONFIG_FUNCTION_GRAPH_TRACER
	.global	ftrace_graph_call
ftrace_graph_call:
	/*
	 * a placeholder for the call to a real tracing function, i.e.
	 * ftrace_graph_caller()
	 */
	nop
#endif
	MCOUNT_RESTORE_REGS
	.global	ftrace_stub
ftrace_stub:
	RETURN_BACK
STD_ENDPROC(ftrace_caller)

#else /* ! CONFIG_DYNAMIC_FTRACE */

	.align	64
STD_ENTRY(__mcount)
	{
	 moveli	r11, hw2_last(ftrace_trace_function)
	 moveli	r13, hw2_last(ftrace_stub)
	}
	{
	 shl16insli	r11, r11, hw1(ftrace_trace_function)
	 shl16insli	r13, r13, hw1(ftrace_stub)
	}
	{
	 shl16insli	r11, r11, hw0(ftrace_trace_function)
	 shl16insli	r13, r13, hw0(ftrace_stub)
	}

	ld	r11, r11
	sub	r14, r13, r11
	bnez	r14, static_trace

#ifdef	CONFIG_FUNCTION_GRAPH_TRACER
	moveli	r15, hw2_last(ftrace_graph_return)
	shl16insli	r15, r15, hw1(ftrace_graph_return)
	shl16insli	r15, r15, hw0(ftrace_graph_return)
	ld	r15, r15
	sub	r15, r15, r13
	bnez	r15, ftrace_graph_caller

	{
	 moveli	r16, hw2_last(ftrace_graph_entry)
	 moveli	r17, hw2_last(ftrace_graph_entry_stub)
	}
	{
	 shl16insli	r16, r16, hw1(ftrace_graph_entry)
	 shl16insli	r17, r17, hw1(ftrace_graph_entry_stub)
	}
	{
	 shl16insli	r16, r16, hw0(ftrace_graph_entry)
	 shl16insli	r17, r17, hw0(ftrace_graph_entry_stub)
	}
	ld	r16, r16
	sub	r17, r16, r17
	bnez	r17, ftrace_graph_caller

#endif
	RETURN_BACK

static_trace:
	MCOUNT_SAVE_REGS

	/* arg1: self return address */
	/* arg2: parent's return address */
	{ move	r0, lr; move	r1, r10 }

	/* call ftrace_trace_function() */
	jalr	r11

	MCOUNT_RESTORE_REGS

	.global ftrace_stub
ftrace_stub:
	RETURN_BACK
STD_ENDPROC(__mcount)

#endif	/* ! CONFIG_DYNAMIC_FTRACE */

#ifdef CONFIG_FUNCTION_GRAPH_TRACER

STD_ENTRY(ftrace_graph_caller)
ftrace_graph_caller:
#ifndef CONFIG_DYNAMIC_FTRACE
	MCOUNT_SAVE_REGS
#endif

	/* arg1: Get the location of the parent's return address */
	addi	r0, sp, 12 * REGSIZE
	/* arg2: Get self return address */
	move	r1, lr

	jal prepare_ftrace_return

	MCOUNT_RESTORE_REGS
	RETURN_BACK
STD_ENDPROC(ftrace_graph_caller)

	.global return_to_handler
return_to_handler:
	MCOUNT_SAVE_REGS

	jal	ftrace_return_to_handler
	/* restore the real parent address */
	move	r11, r0

	MCOUNT_RESTORE_REGS
	jr	r11

#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
