blob: 47041d19d4a8c5019845cd53dbaf8b8c6c1f017f [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
Linus Torvalds1da177e2005-04-16 15:20:36 -070012
13#ifndef __STR
14#ifdef __ASSEMBLY__
15#define __STR(x) x
16#else
17#define __STR(x) #x
18#endif
19#endif /* __STR */
20
21#ifdef CONFIG_SMP
22#define M32R_LOCK __STR(lock)
23#define M32R_UNLOCK __STR(unlock)
24#else
25#define M32R_LOCK __STR(ld)
26#define M32R_UNLOCK __STR(st)
27#endif
28
29#ifdef __ASSEMBLY__
30#undef ENTRY
31#define ENTRY(name) ENTRY_M name
32 .macro ENTRY_M name
33 .global \name
34 ALIGN
35\name:
36 .endm
37#endif
38
39
40/**
41 * LDIMM - load immediate value
42 * STI - enable interruption
43 * CLI - disable interruption
44 */
45
46#ifdef __ASSEMBLY__
47
48#define LDIMM(reg,x) LDIMM reg x
49 .macro LDIMM reg x
50 seth \reg, #high(\x)
51 or3 \reg, \reg, #low(\x)
52 .endm
53
Hirokazu Takata9287d952006-01-06 00:18:41 -080054#if !(defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_M32104))
Linus Torvalds1da177e2005-04-16 15:20:36 -070055#define STI(reg) STI_M reg
56 .macro STI_M reg
57 setpsw #0x40 -> nop
58 ; WORKAROUND: "-> nop" is a workaround for the M32700(TS1).
59 .endm
60
61#define CLI(reg) CLI_M reg
62 .macro CLI_M reg
63 clrpsw #0x40 -> nop
64 ; WORKAROUND: "-> nop" is a workaround for the M32700(TS1).
65 .endm
Hirokazu Takata9287d952006-01-06 00:18:41 -080066#else /* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
Linus Torvalds1da177e2005-04-16 15:20:36 -070067#define STI(reg) STI_M reg
68 .macro STI_M reg
69 mvfc \reg, psw
70 or3 \reg, \reg, #0x0040
71 mvtc \reg, psw
72 .endm
73
74#define CLI(reg) CLI_M reg
75 .macro CLI_M reg
76 mvfc \reg, psw
77 and3 \reg, \reg, #0xffbf
78 mvtc \reg, psw
79 .endm
80#endif /* CONFIG_CHIP_M32102 */
81
82 .macro SAVE_ALL
83 push r0 ; orig_r0
84 push sp ; spi (r15)
85 push lr ; r14
86 push r13
87 mvfc r13, cr3 ; spu
88 push r13
89 mvfc r13, bbpc
90 push r13
91 mvfc r13, bbpsw
92 push r13
93 mvfc r13, bpc
94 push r13
95 mvfc r13, psw
96 push r13
97#if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2)
98 mvfaclo r13, a1
99 push r13
100 mvfachi r13, a1
101 push r13
102 mvfaclo r13, a0
103 push r13
104 mvfachi r13, a0
105 push r13
106#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
107 mvfaclo r13
108 push r13
109 mvfachi r13
110 push r13
Hirokazu Takata8e8ff022006-04-18 22:21:20 -0700111 ldi r13, #0
112 push r13 ; dummy push acc1h
113 push r13 ; dummy push acc1l
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114#else
115#error unknown isa configuration
116#endif
117 ldi r13, #-1
118 push r13 ; syscall_nr (default: -1)
119 push r12
120 push r11
121 push r10
122 push r9
123 push r8
124 push r7
125 push r3
126 push r2
127 push r1
128 push r0
129 addi sp, #-4 ; room for implicit pt_regs parameter
130 push r6
131 push r5
132 push r4
133 .endm
134
135 .macro RESTORE_ALL
136 pop r4
137 pop r5
138 pop r6
139 addi sp, #4
140 pop r0
141 pop r1
142 pop r2
143 pop r3
144 pop r7
145 pop r8
146 pop r9
147 pop r10
148 pop r11
149 pop r12
150 addi r15, #4 ; Skip syscall number
151#if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2)
152 pop r13
153 mvtachi r13, a0
154 pop r13
155 mvtaclo r13, a0
156 pop r13
157 mvtachi r13, a1
158 pop r13
159 mvtaclo r13, a1
160#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
Hirokazu Takata8e8ff022006-04-18 22:21:20 -0700161 pop r13 ; dummy pop acc1h
162 pop r13 ; dummy pop acc1l
Linus Torvalds1da177e2005-04-16 15:20:36 -0700163 pop r13
164 mvtachi r13
165 pop r13
166 mvtaclo r13
167#else
168#error unknown isa configuration
169#endif
170 pop r14
171 mvtc r14, psw
172 pop r14
173 mvtc r14, bpc
174 addi sp, #8 ; Skip bbpsw, bbpc
175 pop r14
176 mvtc r14, cr3 ; spu
177 pop r13
178 pop lr ; r14
179 pop sp ; spi (r15)
180 addi sp, #4 ; Skip orig_r0
181 .fillinsn
1821: rte
183 .section .fixup,"ax"
1842: bl do_exit
185 .previous
186 .section __ex_table,"a"
187 ALIGN
188 .long 1b, 2b
189 .previous
190 .endm
191
192#define GET_CURRENT(reg) get_current reg
193 .macro get_current reg
194 ldi \reg, #-8192
195 and \reg, sp
196 .endm
197
Hirokazu Takata9287d952006-01-06 00:18:41 -0800198#if !(defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_M32104))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199 .macro SWITCH_TO_KERNEL_STACK
200 ; switch to kernel stack (spi)
201 clrpsw #0x80 -> nop
202 .endm
Hirokazu Takata9287d952006-01-06 00:18:41 -0800203#else /* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204 .macro SWITCH_TO_KERNEL_STACK
205 push r0 ; save r0 for working
206 mvfc r0, psw
207 and3 r0, r0, #0x00ff7f
208 mvtc r0, psw
209 slli r0, #16
210 bltz r0, 1f ; check BSM-bit
211;
212 ;; called from kernel context: previous stack = spi
213 pop r0 ; retrieve r0
214 bra 2f
215 .fillinsn
2161:
217 ;; called from user context: previous stack = spu
218 mvfc r0, cr3 ; spu
219 addi r0, #4
220 mvtc r0, cr3 ; spu
221 ld r0, @(-4,r0) ; retrieve r0
222 .fillinsn
2232:
224 .endm
Hirokazu Takata9287d952006-01-06 00:18:41 -0800225#endif /* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226
227#endif /* __ASSEMBLY__ */
228
229#endif /* _ASM_M32R_ASSEMBLER_H */