• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
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 
54 #if !(defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_M32104))
55 #define ENABLE_INTERRUPTS(reg) ENABLE_INTERRUPTS reg
56 	.macro ENABLE_INTERRUPTS reg
57 	setpsw  #0x40	    ->	nop
58 	; WORKAROUND: "-> nop" is a workaround for the M32700(TS1).
59 	.endm
60 
61 #define DISABLE_INTERRUPTS(reg) DISABLE_INTERRUPTS reg
62 	.macro DISABLE_INTERRUPTS reg
63 	clrpsw  #0x40	    ->	nop
64 	; WORKAROUND: "-> nop" is a workaround for the M32700(TS1).
65 	.endm
66 #else	/* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
67 #define ENABLE_INTERRUPTS(reg) ENABLE_INTERRUPTS reg
68 	.macro ENABLE_INTERRUPTS reg
69 	mvfc	\reg, psw
70 	or3	\reg, \reg, #0x0040
71 	mvtc	\reg, psw
72 	.endm
73 
74 #define DISABLE_INTERRUPTS(reg) DISABLE_INTERRUPTS reg
75 	.macro DISABLE_INTERRUPTS 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
111 	ldi	r13, #0
112 	push	r13		; dummy push acc1h
113 	push	r13		; dummy push acc1l
114 #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)
161 	pop	r13		; dummy pop acc1h
162 	pop	r13		; dummy pop acc1l
163 	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
182 1:	rte
183 	.section .fixup,"ax"
184 2:	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 
198 #if !(defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_M32104))
199 	.macro	SWITCH_TO_KERNEL_STACK
200 	; switch to kernel stack (spi)
201 	clrpsw	#0x80	    ->	nop
202 	.endm
203 #else	/* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
204 	.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
216 1:
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
223 2:
224 	.endm
225 #endif	/* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
226 
227 #endif	/* __ASSEMBLY__ */
228 
229 #endif	/* _ASM_M32R_ASSEMBLER_H */
230