Merge branch 'timers-for-linus-clockevents' of git://git.kernel.org/pub/scm/linux...
[linux-2.6] / arch / m32r / include / asm / assembler.h
1 #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
12 #include <linux/stringify.h>
13
14 #undef __STR
15
16 #ifdef __ASSEMBLY__
17 #define __STR(x) x
18 #else
19 #define __STR(x) __stringify(x)
20 #endif
21
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
55 #if !(defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_M32104))
56 #define ENABLE_INTERRUPTS(reg) ENABLE_INTERRUPTS reg
57         .macro ENABLE_INTERRUPTS reg
58         setpsw  #0x40       ->  nop
59         ; WORKAROUND: "-> nop" is a workaround for the M32700(TS1).
60         .endm
61
62 #define DISABLE_INTERRUPTS(reg) DISABLE_INTERRUPTS reg
63         .macro DISABLE_INTERRUPTS reg
64         clrpsw  #0x40       ->  nop
65         ; WORKAROUND: "-> nop" is a workaround for the M32700(TS1).
66         .endm
67 #else   /* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
68 #define ENABLE_INTERRUPTS(reg) ENABLE_INTERRUPTS reg
69         .macro ENABLE_INTERRUPTS reg
70         mvfc    \reg, psw
71         or3     \reg, \reg, #0x0040
72         mvtc    \reg, psw
73         .endm
74
75 #define DISABLE_INTERRUPTS(reg) DISABLE_INTERRUPTS reg
76         .macro DISABLE_INTERRUPTS reg
77         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
112         ldi     r13, #0
113         push    r13             ; dummy push acc1h
114         push    r13             ; dummy push acc1l
115 #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)
162         pop     r13             ; dummy pop acc1h
163         pop     r13             ; dummy pop acc1l
164         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
183 1:      rte
184         .section .fixup,"ax"
185 2:      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
199 #if !(defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_M32104))
200         .macro  SWITCH_TO_KERNEL_STACK
201         ; switch to kernel stack (spi)
202         clrpsw  #0x80       ->  nop
203         .endm
204 #else   /* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
205         .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
217 1:
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
224 2:
225         .endm
226 #endif  /* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
227
228 #endif  /* __ASSEMBLY__ */
229
230 #endif  /* _ASM_M32R_ASSEMBLER_H */