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