| /* |
| * 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) 2001 Hiroyuki Kondo, Hirokazu Takata, and Hitoshi Yamamoto |
| * Copyright (C) 2004, 2006 Hirokazu Takata <takata at linux-m32r.org> |
| */ |
| #ifndef _ASM_M32R_SWITCH_TO_H |
| #define _ASM_M32R_SWITCH_TO_H |
| |
| /* |
| * switch_to(prev, next) should switch from task `prev' to `next' |
| * `prev' will never be the same as `next'. |
| * |
| * `next' and `prev' should be struct task_struct, but it isn't always defined |
| */ |
| |
| #if defined(CONFIG_FRAME_POINTER) || \ |
| !defined(CONFIG_SCHED_OMIT_FRAME_POINTER) |
| #define M32R_PUSH_FP " push fp\n" |
| #define M32R_POP_FP " pop fp\n" |
| #else |
| #define M32R_PUSH_FP "" |
| #define M32R_POP_FP "" |
| #endif |
| |
| #define switch_to(prev, next, last) do { \ |
| __asm__ __volatile__ ( \ |
| " seth lr, #high(1f) \n" \ |
| " or3 lr, lr, #low(1f) \n" \ |
| " st lr, @%4 ; store old LR \n" \ |
| " ld lr, @%5 ; load new LR \n" \ |
| M32R_PUSH_FP \ |
| " st sp, @%2 ; store old SP \n" \ |
| " ld sp, @%3 ; load new SP \n" \ |
| " push %1 ; store `prev' on new stack \n" \ |
| " jmp lr \n" \ |
| " .fillinsn \n" \ |
| "1: \n" \ |
| " pop %0 ; restore `__last' from new stack \n" \ |
| M32R_POP_FP \ |
| : "=r" (last) \ |
| : "0" (prev), \ |
| "r" (&(prev->thread.sp)), "r" (&(next->thread.sp)), \ |
| "r" (&(prev->thread.lr)), "r" (&(next->thread.lr)) \ |
| : "memory", "lr" \ |
| ); \ |
| } while(0) |
| |
| #endif /* _ASM_M32R_SWITCH_TO_H */ |