xref: /openbmc/linux/arch/mips/include/asm/asmmacro.h (revision d2999e1b)
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 2003 Ralf Baechle
7  */
8 #ifndef _ASM_ASMMACRO_H
9 #define _ASM_ASMMACRO_H
10 
11 #include <asm/hazards.h>
12 #include <asm/asm-offsets.h>
13 
14 #ifdef CONFIG_32BIT
15 #include <asm/asmmacro-32.h>
16 #endif
17 #ifdef CONFIG_64BIT
18 #include <asm/asmmacro-64.h>
19 #endif
20 
21 #ifdef CONFIG_CPU_MIPSR2
22 	.macro	local_irq_enable reg=t0
23 	ei
24 	irq_enable_hazard
25 	.endm
26 
27 	.macro	local_irq_disable reg=t0
28 	di
29 	irq_disable_hazard
30 	.endm
31 #else
32 	.macro	local_irq_enable reg=t0
33 	mfc0	\reg, CP0_STATUS
34 	ori	\reg, \reg, 1
35 	mtc0	\reg, CP0_STATUS
36 	irq_enable_hazard
37 	.endm
38 
39 	.macro	local_irq_disable reg=t0
40 #ifdef CONFIG_PREEMPT
41 	lw      \reg, TI_PRE_COUNT($28)
42 	addi    \reg, \reg, 1
43 	sw      \reg, TI_PRE_COUNT($28)
44 #endif
45 	mfc0	\reg, CP0_STATUS
46 	ori	\reg, \reg, 1
47 	xori	\reg, \reg, 1
48 	mtc0	\reg, CP0_STATUS
49 	irq_disable_hazard
50 #ifdef CONFIG_PREEMPT
51 	lw      \reg, TI_PRE_COUNT($28)
52 	addi    \reg, \reg, -1
53 	sw      \reg, TI_PRE_COUNT($28)
54 #endif
55 	.endm
56 #endif /* CONFIG_CPU_MIPSR2 */
57 
58 	.macro	fpu_save_16even thread tmp=t0
59 	cfc1	\tmp, fcr31
60 	sdc1	$f0,  THREAD_FPR0_LS64(\thread)
61 	sdc1	$f2,  THREAD_FPR2_LS64(\thread)
62 	sdc1	$f4,  THREAD_FPR4_LS64(\thread)
63 	sdc1	$f6,  THREAD_FPR6_LS64(\thread)
64 	sdc1	$f8,  THREAD_FPR8_LS64(\thread)
65 	sdc1	$f10, THREAD_FPR10_LS64(\thread)
66 	sdc1	$f12, THREAD_FPR12_LS64(\thread)
67 	sdc1	$f14, THREAD_FPR14_LS64(\thread)
68 	sdc1	$f16, THREAD_FPR16_LS64(\thread)
69 	sdc1	$f18, THREAD_FPR18_LS64(\thread)
70 	sdc1	$f20, THREAD_FPR20_LS64(\thread)
71 	sdc1	$f22, THREAD_FPR22_LS64(\thread)
72 	sdc1	$f24, THREAD_FPR24_LS64(\thread)
73 	sdc1	$f26, THREAD_FPR26_LS64(\thread)
74 	sdc1	$f28, THREAD_FPR28_LS64(\thread)
75 	sdc1	$f30, THREAD_FPR30_LS64(\thread)
76 	sw	\tmp, THREAD_FCR31(\thread)
77 	.endm
78 
79 	.macro	fpu_save_16odd thread
80 	.set	push
81 	.set	mips64r2
82 	sdc1	$f1,  THREAD_FPR1_LS64(\thread)
83 	sdc1	$f3,  THREAD_FPR3_LS64(\thread)
84 	sdc1	$f5,  THREAD_FPR5_LS64(\thread)
85 	sdc1	$f7,  THREAD_FPR7_LS64(\thread)
86 	sdc1	$f9,  THREAD_FPR9_LS64(\thread)
87 	sdc1	$f11, THREAD_FPR11_LS64(\thread)
88 	sdc1	$f13, THREAD_FPR13_LS64(\thread)
89 	sdc1	$f15, THREAD_FPR15_LS64(\thread)
90 	sdc1	$f17, THREAD_FPR17_LS64(\thread)
91 	sdc1	$f19, THREAD_FPR19_LS64(\thread)
92 	sdc1	$f21, THREAD_FPR21_LS64(\thread)
93 	sdc1	$f23, THREAD_FPR23_LS64(\thread)
94 	sdc1	$f25, THREAD_FPR25_LS64(\thread)
95 	sdc1	$f27, THREAD_FPR27_LS64(\thread)
96 	sdc1	$f29, THREAD_FPR29_LS64(\thread)
97 	sdc1	$f31, THREAD_FPR31_LS64(\thread)
98 	.set	pop
99 	.endm
100 
101 	.macro	fpu_save_double thread status tmp
102 #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2)
103 	sll	\tmp, \status, 5
104 	bgez	\tmp, 10f
105 	fpu_save_16odd \thread
106 10:
107 #endif
108 	fpu_save_16even \thread \tmp
109 	.endm
110 
111 	.macro	fpu_restore_16even thread tmp=t0
112 	lw	\tmp, THREAD_FCR31(\thread)
113 	ldc1	$f0,  THREAD_FPR0_LS64(\thread)
114 	ldc1	$f2,  THREAD_FPR2_LS64(\thread)
115 	ldc1	$f4,  THREAD_FPR4_LS64(\thread)
116 	ldc1	$f6,  THREAD_FPR6_LS64(\thread)
117 	ldc1	$f8,  THREAD_FPR8_LS64(\thread)
118 	ldc1	$f10, THREAD_FPR10_LS64(\thread)
119 	ldc1	$f12, THREAD_FPR12_LS64(\thread)
120 	ldc1	$f14, THREAD_FPR14_LS64(\thread)
121 	ldc1	$f16, THREAD_FPR16_LS64(\thread)
122 	ldc1	$f18, THREAD_FPR18_LS64(\thread)
123 	ldc1	$f20, THREAD_FPR20_LS64(\thread)
124 	ldc1	$f22, THREAD_FPR22_LS64(\thread)
125 	ldc1	$f24, THREAD_FPR24_LS64(\thread)
126 	ldc1	$f26, THREAD_FPR26_LS64(\thread)
127 	ldc1	$f28, THREAD_FPR28_LS64(\thread)
128 	ldc1	$f30, THREAD_FPR30_LS64(\thread)
129 	ctc1	\tmp, fcr31
130 	.endm
131 
132 	.macro	fpu_restore_16odd thread
133 	.set	push
134 	.set	mips64r2
135 	ldc1	$f1,  THREAD_FPR1_LS64(\thread)
136 	ldc1	$f3,  THREAD_FPR3_LS64(\thread)
137 	ldc1	$f5,  THREAD_FPR5_LS64(\thread)
138 	ldc1	$f7,  THREAD_FPR7_LS64(\thread)
139 	ldc1	$f9,  THREAD_FPR9_LS64(\thread)
140 	ldc1	$f11, THREAD_FPR11_LS64(\thread)
141 	ldc1	$f13, THREAD_FPR13_LS64(\thread)
142 	ldc1	$f15, THREAD_FPR15_LS64(\thread)
143 	ldc1	$f17, THREAD_FPR17_LS64(\thread)
144 	ldc1	$f19, THREAD_FPR19_LS64(\thread)
145 	ldc1	$f21, THREAD_FPR21_LS64(\thread)
146 	ldc1	$f23, THREAD_FPR23_LS64(\thread)
147 	ldc1	$f25, THREAD_FPR25_LS64(\thread)
148 	ldc1	$f27, THREAD_FPR27_LS64(\thread)
149 	ldc1	$f29, THREAD_FPR29_LS64(\thread)
150 	ldc1	$f31, THREAD_FPR31_LS64(\thread)
151 	.set	pop
152 	.endm
153 
154 	.macro	fpu_restore_double thread status tmp
155 #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2)
156 	sll	\tmp, \status, 5
157 	bgez	\tmp, 10f				# 16 register mode?
158 
159 	fpu_restore_16odd \thread
160 10:
161 #endif
162 	fpu_restore_16even \thread \tmp
163 	.endm
164 
165 #ifdef CONFIG_CPU_MIPSR2
166 	.macro	_EXT	rd, rs, p, s
167 	ext	\rd, \rs, \p, \s
168 	.endm
169 #else /* !CONFIG_CPU_MIPSR2 */
170 	.macro	_EXT	rd, rs, p, s
171 	srl	\rd, \rs, \p
172 	andi	\rd, \rd, (1 << \s) - 1
173 	.endm
174 #endif /* !CONFIG_CPU_MIPSR2 */
175 
176 /*
177  * Temporary until all gas have MT ASE support
178  */
179 	.macro	DMT	reg=0
180 	.word	0x41600bc1 | (\reg << 16)
181 	.endm
182 
183 	.macro	EMT	reg=0
184 	.word	0x41600be1 | (\reg << 16)
185 	.endm
186 
187 	.macro	DVPE	reg=0
188 	.word	0x41600001 | (\reg << 16)
189 	.endm
190 
191 	.macro	EVPE	reg=0
192 	.word	0x41600021 | (\reg << 16)
193 	.endm
194 
195 	.macro	MFTR	rt=0, rd=0, u=0, sel=0
196 	 .word	0x41000000 | (\rt << 16) | (\rd << 11) | (\u << 5) | (\sel)
197 	.endm
198 
199 	.macro	MTTR	rt=0, rd=0, u=0, sel=0
200 	 .word	0x41800000 | (\rt << 16) | (\rd << 11) | (\u << 5) | (\sel)
201 	.endm
202 
203 #ifdef TOOLCHAIN_SUPPORTS_MSA
204 	.macro	ld_d	wd, off, base
205 	.set	push
206 	.set	mips32r2
207 	.set	msa
208 	ld.d	$w\wd, \off(\base)
209 	.set	pop
210 	.endm
211 
212 	.macro	st_d	wd, off, base
213 	.set	push
214 	.set	mips32r2
215 	.set	msa
216 	st.d	$w\wd, \off(\base)
217 	.set	pop
218 	.endm
219 
220 	.macro	copy_u_w	rd, ws, n
221 	.set	push
222 	.set	mips32r2
223 	.set	msa
224 	copy_u.w \rd, $w\ws[\n]
225 	.set	pop
226 	.endm
227 
228 	.macro	copy_u_d	rd, ws, n
229 	.set	push
230 	.set	mips64r2
231 	.set	msa
232 	copy_u.d \rd, $w\ws[\n]
233 	.set	pop
234 	.endm
235 
236 	.macro	insert_w	wd, n, rs
237 	.set	push
238 	.set	mips32r2
239 	.set	msa
240 	insert.w $w\wd[\n], \rs
241 	.set	pop
242 	.endm
243 
244 	.macro	insert_d	wd, n, rs
245 	.set	push
246 	.set	mips64r2
247 	.set	msa
248 	insert.d $w\wd[\n], \rs
249 	.set	pop
250 	.endm
251 #else
252 
253 #ifdef CONFIG_CPU_MICROMIPS
254 #define CFC_MSA_INSN		0x587e0056
255 #define CTC_MSA_INSN		0x583e0816
256 #define LDD_MSA_INSN		0x58000837
257 #define STD_MSA_INSN		0x5800083f
258 #define COPY_UW_MSA_INSN	0x58f00056
259 #define COPY_UD_MSA_INSN	0x58f80056
260 #define INSERT_W_MSA_INSN	0x59300816
261 #define INSERT_D_MSA_INSN	0x59380816
262 #else
263 #define CFC_MSA_INSN		0x787e0059
264 #define CTC_MSA_INSN		0x783e0819
265 #define LDD_MSA_INSN		0x78000823
266 #define STD_MSA_INSN		0x78000827
267 #define COPY_UW_MSA_INSN	0x78f00059
268 #define COPY_UD_MSA_INSN	0x78f80059
269 #define INSERT_W_MSA_INSN	0x79300819
270 #define INSERT_D_MSA_INSN	0x79380819
271 #endif
272 
273 	/*
274 	 * Temporary until all toolchains in use include MSA support.
275 	 */
276 	.macro	cfcmsa	rd, cs
277 	.set	push
278 	.set	noat
279 	.insn
280 	.word	CFC_MSA_INSN | (\cs << 11)
281 	move	\rd, $1
282 	.set	pop
283 	.endm
284 
285 	.macro	ctcmsa	cd, rs
286 	.set	push
287 	.set	noat
288 	move	$1, \rs
289 	.word	CTC_MSA_INSN | (\cd << 6)
290 	.set	pop
291 	.endm
292 
293 	.macro	ld_d	wd, off, base
294 	.set	push
295 	.set	noat
296 	add	$1, \base, \off
297 	.word	LDD_MSA_INSN | (\wd << 6)
298 	.set	pop
299 	.endm
300 
301 	.macro	st_d	wd, off, base
302 	.set	push
303 	.set	noat
304 	add	$1, \base, \off
305 	.word	STD_MSA_INSN | (\wd << 6)
306 	.set	pop
307 	.endm
308 
309 	.macro	copy_u_w	rd, ws, n
310 	.set	push
311 	.set	noat
312 	.insn
313 	.word	COPY_UW_MSA_INSN | (\n << 16) | (\ws << 11)
314 	/* move triggers an assembler bug... */
315 	or	\rd, $1, zero
316 	.set	pop
317 	.endm
318 
319 	.macro	copy_u_d	rd, ws, n
320 	.set	push
321 	.set	noat
322 	.insn
323 	.word	COPY_UD_MSA_INSN | (\n << 16) | (\ws << 11)
324 	/* move triggers an assembler bug... */
325 	or	\rd, $1, zero
326 	.set	pop
327 	.endm
328 
329 	.macro	insert_w	wd, n, rs
330 	.set	push
331 	.set	noat
332 	/* move triggers an assembler bug... */
333 	or	$1, \rs, zero
334 	.word	INSERT_W_MSA_INSN | (\n << 16) | (\wd << 6)
335 	.set	pop
336 	.endm
337 
338 	.macro	insert_d	wd, n, rs
339 	.set	push
340 	.set	noat
341 	/* move triggers an assembler bug... */
342 	or	$1, \rs, zero
343 	.word	INSERT_D_MSA_INSN | (\n << 16) | (\wd << 6)
344 	.set	pop
345 	.endm
346 #endif
347 
348 	.macro	msa_save_all	thread
349 	st_d	0, THREAD_FPR0, \thread
350 	st_d	1, THREAD_FPR1, \thread
351 	st_d	2, THREAD_FPR2, \thread
352 	st_d	3, THREAD_FPR3, \thread
353 	st_d	4, THREAD_FPR4, \thread
354 	st_d	5, THREAD_FPR5, \thread
355 	st_d	6, THREAD_FPR6, \thread
356 	st_d	7, THREAD_FPR7, \thread
357 	st_d	8, THREAD_FPR8, \thread
358 	st_d	9, THREAD_FPR9, \thread
359 	st_d	10, THREAD_FPR10, \thread
360 	st_d	11, THREAD_FPR11, \thread
361 	st_d	12, THREAD_FPR12, \thread
362 	st_d	13, THREAD_FPR13, \thread
363 	st_d	14, THREAD_FPR14, \thread
364 	st_d	15, THREAD_FPR15, \thread
365 	st_d	16, THREAD_FPR16, \thread
366 	st_d	17, THREAD_FPR17, \thread
367 	st_d	18, THREAD_FPR18, \thread
368 	st_d	19, THREAD_FPR19, \thread
369 	st_d	20, THREAD_FPR20, \thread
370 	st_d	21, THREAD_FPR21, \thread
371 	st_d	22, THREAD_FPR22, \thread
372 	st_d	23, THREAD_FPR23, \thread
373 	st_d	24, THREAD_FPR24, \thread
374 	st_d	25, THREAD_FPR25, \thread
375 	st_d	26, THREAD_FPR26, \thread
376 	st_d	27, THREAD_FPR27, \thread
377 	st_d	28, THREAD_FPR28, \thread
378 	st_d	29, THREAD_FPR29, \thread
379 	st_d	30, THREAD_FPR30, \thread
380 	st_d	31, THREAD_FPR31, \thread
381 	.endm
382 
383 	.macro	msa_restore_all	thread
384 	ld_d	0, THREAD_FPR0, \thread
385 	ld_d	1, THREAD_FPR1, \thread
386 	ld_d	2, THREAD_FPR2, \thread
387 	ld_d	3, THREAD_FPR3, \thread
388 	ld_d	4, THREAD_FPR4, \thread
389 	ld_d	5, THREAD_FPR5, \thread
390 	ld_d	6, THREAD_FPR6, \thread
391 	ld_d	7, THREAD_FPR7, \thread
392 	ld_d	8, THREAD_FPR8, \thread
393 	ld_d	9, THREAD_FPR9, \thread
394 	ld_d	10, THREAD_FPR10, \thread
395 	ld_d	11, THREAD_FPR11, \thread
396 	ld_d	12, THREAD_FPR12, \thread
397 	ld_d	13, THREAD_FPR13, \thread
398 	ld_d	14, THREAD_FPR14, \thread
399 	ld_d	15, THREAD_FPR15, \thread
400 	ld_d	16, THREAD_FPR16, \thread
401 	ld_d	17, THREAD_FPR17, \thread
402 	ld_d	18, THREAD_FPR18, \thread
403 	ld_d	19, THREAD_FPR19, \thread
404 	ld_d	20, THREAD_FPR20, \thread
405 	ld_d	21, THREAD_FPR21, \thread
406 	ld_d	22, THREAD_FPR22, \thread
407 	ld_d	23, THREAD_FPR23, \thread
408 	ld_d	24, THREAD_FPR24, \thread
409 	ld_d	25, THREAD_FPR25, \thread
410 	ld_d	26, THREAD_FPR26, \thread
411 	ld_d	27, THREAD_FPR27, \thread
412 	ld_d	28, THREAD_FPR28, \thread
413 	ld_d	29, THREAD_FPR29, \thread
414 	ld_d	30, THREAD_FPR30, \thread
415 	ld_d	31, THREAD_FPR31, \thread
416 	.endm
417 
418 #endif /* _ASM_ASMMACRO_H */
419