1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License.  See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2001  Hiroyuki Kondo, Hirokazu Takata, and Hitoshi Yamamoto
7 * Copyright (C) 2004, 2006  Hirokazu Takata <takata at linux-m32r.org>
8 */
9#ifndef _ASM_M32R_SWITCH_TO_H
10#define _ASM_M32R_SWITCH_TO_H
11
12/*
13 * switch_to(prev, next) should switch from task `prev' to `next'
14 * `prev' will never be the same as `next'.
15 *
16 * `next' and `prev' should be struct task_struct, but it isn't always defined
17 */
18
19#if defined(CONFIG_FRAME_POINTER) || \
20	!defined(CONFIG_SCHED_OMIT_FRAME_POINTER)
21#define M32R_PUSH_FP "	push fp\n"
22#define M32R_POP_FP  "	pop  fp\n"
23#else
24#define M32R_PUSH_FP ""
25#define M32R_POP_FP  ""
26#endif
27
28#define switch_to(prev, next, last)  do { \
29	__asm__ __volatile__ ( \
30		"	seth	lr, #high(1f)				\n" \
31		"	or3	lr, lr, #low(1f)			\n" \
32		"	st	lr, @%4  ; store old LR			\n" \
33		"	ld	lr, @%5  ; load new LR			\n" \
34			M32R_PUSH_FP \
35		"	st	sp, @%2  ; store old SP			\n" \
36		"	ld	sp, @%3  ; load new SP			\n" \
37		"	push	%1  ; store `prev' on new stack		\n" \
38		"	jmp	lr					\n" \
39		"	.fillinsn					\n" \
40		"1:							\n" \
41		"	pop	%0  ; restore `__last' from new stack	\n" \
42			M32R_POP_FP \
43		: "=r" (last) \
44		: "0" (prev), \
45		  "r" (&(prev->thread.sp)), "r" (&(next->thread.sp)), \
46		  "r" (&(prev->thread.lr)), "r" (&(next->thread.lr)) \
47		: "memory", "lr" \
48	); \
49} while(0)
50
51#endif /* _ASM_M32R_SWITCH_TO_H */
52