blob: 728799fc70aad7d967c8c9ad7b4a95eca6cbf4aa [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001#ifndef _ASM_M32R_ASSEMBLER_H
2#define _ASM_M32R_ASSEMBLER_H
3
4/*
5 * linux/asm-m32r/assembler.h
6 *
7 * Copyright (C) 2004 Hirokazu Takata <takata at linux-m32r.org>
8 *
9 * This file contains M32R architecture specific macro definitions.
10 */
11
Hirokazu Takata9cd67242009-05-02 22:08:33 +090012#include <linux/stringify.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070013
Hirokazu Takata9cd67242009-05-02 22:08:33 +090014#undef __STR
15
Linus Torvalds1da177e2005-04-16 15:20:36 -070016#ifdef __ASSEMBLY__
17#define __STR(x) x
18#else
Hirokazu Takata9cd67242009-05-02 22:08:33 +090019#define __STR(x) __stringify(x)
Linus Torvalds1da177e2005-04-16 15:20:36 -070020#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070021
22#ifdef CONFIG_SMP
23#define M32R_LOCK __STR(lock)
24#define M32R_UNLOCK __STR(unlock)
25#else
26#define M32R_LOCK __STR(ld)
27#define M32R_UNLOCK __STR(st)
28#endif
29
30#ifdef __ASSEMBLY__
31#undef ENTRY
32#define ENTRY(name) ENTRY_M name
33 .macro ENTRY_M name
34 .global \name
35 ALIGN
36\name:
37 .endm
38#endif
39
40
41/**
42 * LDIMM - load immediate value
43 * STI - enable interruption
44 * CLI - disable interruption
45 */
46
47#ifdef __ASSEMBLY__
48
49#define LDIMM(reg,x) LDIMM reg x
50 .macro LDIMM reg x
51 seth \reg, #high(\x)
52 or3 \reg, \reg, #low(\x)
53 .endm
54
Hirokazu Takata9287d952006-01-06 00:18:41 -080055#if !(defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_M32104))
Hirokazu Takata7071b2912007-08-20 20:53:50 +090056#define ENABLE_INTERRUPTS(reg) ENABLE_INTERRUPTS reg
57 .macro ENABLE_INTERRUPTS reg
Linus Torvalds1da177e2005-04-16 15:20:36 -070058 setpsw #0x40 -> nop
59 ; WORKAROUND: "-> nop" is a workaround for the M32700(TS1).
60 .endm
61
Hirokazu Takata7071b2912007-08-20 20:53:50 +090062#define DISABLE_INTERRUPTS(reg) DISABLE_INTERRUPTS reg
63 .macro DISABLE_INTERRUPTS reg
Linus Torvalds1da177e2005-04-16 15:20:36 -070064 clrpsw #0x40 -> nop
65 ; WORKAROUND: "-> nop" is a workaround for the M32700(TS1).
66 .endm
Hirokazu Takata9287d952006-01-06 00:18:41 -080067#else /* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
Hirokazu Takata7071b2912007-08-20 20:53:50 +090068#define ENABLE_INTERRUPTS(reg) ENABLE_INTERRUPTS reg
69 .macro ENABLE_INTERRUPTS reg
Linus Torvalds1da177e2005-04-16 15:20:36 -070070 mvfc \reg, psw
71 or3 \reg, \reg, #0x0040
72 mvtc \reg, psw
73 .endm
74
Hirokazu Takata7071b2912007-08-20 20:53:50 +090075#define DISABLE_INTERRUPTS(reg) DISABLE_INTERRUPTS reg
76 .macro DISABLE_INTERRUPTS reg
Linus Torvalds1da177e2005-04-16 15:20:36 -070077 mvfc \reg, psw
78 and3 \reg, \reg, #0xffbf
79 mvtc \reg, psw
80 .endm
81#endif /* CONFIG_CHIP_M32102 */
82
83 .macro SAVE_ALL
84 push r0 ; orig_r0
85 push sp ; spi (r15)
86 push lr ; r14
87 push r13
88 mvfc r13, cr3 ; spu
89 push r13
90 mvfc r13, bbpc
91 push r13
92 mvfc r13, bbpsw
93 push r13
94 mvfc r13, bpc
95 push r13
96 mvfc r13, psw
97 push r13
98#if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2)
99 mvfaclo r13, a1
100 push r13
101 mvfachi r13, a1
102 push r13
103 mvfaclo r13, a0
104 push r13
105 mvfachi r13, a0
106 push r13
107#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
108 mvfaclo r13
109 push r13
110 mvfachi r13
111 push r13
Hirokazu Takata8e8ff022006-04-18 22:21:20 -0700112 ldi r13, #0
113 push r13 ; dummy push acc1h
114 push r13 ; dummy push acc1l
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115#else
116#error unknown isa configuration
117#endif
118 ldi r13, #-1
119 push r13 ; syscall_nr (default: -1)
120 push r12
121 push r11
122 push r10
123 push r9
124 push r8
125 push r7
126 push r3
127 push r2
128 push r1
129 push r0
130 addi sp, #-4 ; room for implicit pt_regs parameter
131 push r6
132 push r5
133 push r4
134 .endm
135
136 .macro RESTORE_ALL
137 pop r4
138 pop r5
139 pop r6
140 addi sp, #4
141 pop r0
142 pop r1
143 pop r2
144 pop r3
145 pop r7
146 pop r8
147 pop r9
148 pop r10
149 pop r11
150 pop r12
151 addi r15, #4 ; Skip syscall number
152#if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2)
153 pop r13
154 mvtachi r13, a0
155 pop r13
156 mvtaclo r13, a0
157 pop r13
158 mvtachi r13, a1
159 pop r13
160 mvtaclo r13, a1
161#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
Hirokazu Takata8e8ff022006-04-18 22:21:20 -0700162 pop r13 ; dummy pop acc1h
163 pop r13 ; dummy pop acc1l
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164 pop r13
165 mvtachi r13
166 pop r13
167 mvtaclo r13
168#else
169#error unknown isa configuration
170#endif
171 pop r14
172 mvtc r14, psw
173 pop r14
174 mvtc r14, bpc
175 addi sp, #8 ; Skip bbpsw, bbpc
176 pop r14
177 mvtc r14, cr3 ; spu
178 pop r13
179 pop lr ; r14
180 pop sp ; spi (r15)
181 addi sp, #4 ; Skip orig_r0
182 .fillinsn
1831: rte
184 .section .fixup,"ax"
1852: bl do_exit
186 .previous
187 .section __ex_table,"a"
188 ALIGN
189 .long 1b, 2b
190 .previous
191 .endm
192
193#define GET_CURRENT(reg) get_current reg
194 .macro get_current reg
195 ldi \reg, #-8192
196 and \reg, sp
197 .endm
198
Hirokazu Takata9287d952006-01-06 00:18:41 -0800199#if !(defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_M32104))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200 .macro SWITCH_TO_KERNEL_STACK
201 ; switch to kernel stack (spi)
202 clrpsw #0x80 -> nop
203 .endm
Hirokazu Takata9287d952006-01-06 00:18:41 -0800204#else /* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205 .macro SWITCH_TO_KERNEL_STACK
206 push r0 ; save r0 for working
207 mvfc r0, psw
208 and3 r0, r0, #0x00ff7f
209 mvtc r0, psw
210 slli r0, #16
211 bltz r0, 1f ; check BSM-bit
212;
213 ;; called from kernel context: previous stack = spi
214 pop r0 ; retrieve r0
215 bra 2f
216 .fillinsn
2171:
218 ;; called from user context: previous stack = spu
219 mvfc r0, cr3 ; spu
220 addi r0, #4
221 mvtc r0, cr3 ; spu
222 ld r0, @(-4,r0) ; retrieve r0
223 .fillinsn
2242:
225 .endm
Hirokazu Takata9287d952006-01-06 00:18:41 -0800226#endif /* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227
228#endif /* __ASSEMBLY__ */
229
230#endif /* _ASM_M32R_ASSEMBLER_H */