xref: /openbmc/linux/arch/mips/include/asm/asmmacro.h (revision 4f3db074)
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 #include <asm/msa.h>
14 
15 #ifdef CONFIG_32BIT
16 #include <asm/asmmacro-32.h>
17 #endif
18 #ifdef CONFIG_64BIT
19 #include <asm/asmmacro-64.h>
20 #endif
21 
22 #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
23 	.macro	local_irq_enable reg=t0
24 	ei
25 	irq_enable_hazard
26 	.endm
27 
28 	.macro	local_irq_disable reg=t0
29 	di
30 	irq_disable_hazard
31 	.endm
32 #else
33 	.macro	local_irq_enable reg=t0
34 	mfc0	\reg, CP0_STATUS
35 	ori	\reg, \reg, 1
36 	mtc0	\reg, CP0_STATUS
37 	irq_enable_hazard
38 	.endm
39 
40 	.macro	local_irq_disable reg=t0
41 #ifdef CONFIG_PREEMPT
42 	lw      \reg, TI_PRE_COUNT($28)
43 	addi    \reg, \reg, 1
44 	sw      \reg, TI_PRE_COUNT($28)
45 #endif
46 	mfc0	\reg, CP0_STATUS
47 	ori	\reg, \reg, 1
48 	xori	\reg, \reg, 1
49 	mtc0	\reg, CP0_STATUS
50 	irq_disable_hazard
51 #ifdef CONFIG_PREEMPT
52 	lw      \reg, TI_PRE_COUNT($28)
53 	addi    \reg, \reg, -1
54 	sw      \reg, TI_PRE_COUNT($28)
55 #endif
56 	.endm
57 #endif /* CONFIG_CPU_MIPSR2 */
58 
59 	.macro	fpu_save_16even thread tmp=t0
60 	.set	push
61 	SET_HARDFLOAT
62 	cfc1	\tmp, fcr31
63 	sdc1	$f0,  THREAD_FPR0(\thread)
64 	sdc1	$f2,  THREAD_FPR2(\thread)
65 	sdc1	$f4,  THREAD_FPR4(\thread)
66 	sdc1	$f6,  THREAD_FPR6(\thread)
67 	sdc1	$f8,  THREAD_FPR8(\thread)
68 	sdc1	$f10, THREAD_FPR10(\thread)
69 	sdc1	$f12, THREAD_FPR12(\thread)
70 	sdc1	$f14, THREAD_FPR14(\thread)
71 	sdc1	$f16, THREAD_FPR16(\thread)
72 	sdc1	$f18, THREAD_FPR18(\thread)
73 	sdc1	$f20, THREAD_FPR20(\thread)
74 	sdc1	$f22, THREAD_FPR22(\thread)
75 	sdc1	$f24, THREAD_FPR24(\thread)
76 	sdc1	$f26, THREAD_FPR26(\thread)
77 	sdc1	$f28, THREAD_FPR28(\thread)
78 	sdc1	$f30, THREAD_FPR30(\thread)
79 	sw	\tmp, THREAD_FCR31(\thread)
80 	.set	pop
81 	.endm
82 
83 	.macro	fpu_save_16odd thread
84 	.set	push
85 	.set	mips64r2
86 	SET_HARDFLOAT
87 	sdc1	$f1,  THREAD_FPR1(\thread)
88 	sdc1	$f3,  THREAD_FPR3(\thread)
89 	sdc1	$f5,  THREAD_FPR5(\thread)
90 	sdc1	$f7,  THREAD_FPR7(\thread)
91 	sdc1	$f9,  THREAD_FPR9(\thread)
92 	sdc1	$f11, THREAD_FPR11(\thread)
93 	sdc1	$f13, THREAD_FPR13(\thread)
94 	sdc1	$f15, THREAD_FPR15(\thread)
95 	sdc1	$f17, THREAD_FPR17(\thread)
96 	sdc1	$f19, THREAD_FPR19(\thread)
97 	sdc1	$f21, THREAD_FPR21(\thread)
98 	sdc1	$f23, THREAD_FPR23(\thread)
99 	sdc1	$f25, THREAD_FPR25(\thread)
100 	sdc1	$f27, THREAD_FPR27(\thread)
101 	sdc1	$f29, THREAD_FPR29(\thread)
102 	sdc1	$f31, THREAD_FPR31(\thread)
103 	.set	pop
104 	.endm
105 
106 	.macro	fpu_save_double thread status tmp
107 #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \
108 		defined(CONFIG_CPU_MIPS32_R6)
109 	sll	\tmp, \status, 5
110 	bgez	\tmp, 10f
111 	fpu_save_16odd \thread
112 10:
113 #endif
114 	fpu_save_16even \thread \tmp
115 	.endm
116 
117 	.macro	fpu_restore_16even thread tmp=t0
118 	.set	push
119 	SET_HARDFLOAT
120 	lw	\tmp, THREAD_FCR31(\thread)
121 	ldc1	$f0,  THREAD_FPR0(\thread)
122 	ldc1	$f2,  THREAD_FPR2(\thread)
123 	ldc1	$f4,  THREAD_FPR4(\thread)
124 	ldc1	$f6,  THREAD_FPR6(\thread)
125 	ldc1	$f8,  THREAD_FPR8(\thread)
126 	ldc1	$f10, THREAD_FPR10(\thread)
127 	ldc1	$f12, THREAD_FPR12(\thread)
128 	ldc1	$f14, THREAD_FPR14(\thread)
129 	ldc1	$f16, THREAD_FPR16(\thread)
130 	ldc1	$f18, THREAD_FPR18(\thread)
131 	ldc1	$f20, THREAD_FPR20(\thread)
132 	ldc1	$f22, THREAD_FPR22(\thread)
133 	ldc1	$f24, THREAD_FPR24(\thread)
134 	ldc1	$f26, THREAD_FPR26(\thread)
135 	ldc1	$f28, THREAD_FPR28(\thread)
136 	ldc1	$f30, THREAD_FPR30(\thread)
137 	ctc1	\tmp, fcr31
138 	.endm
139 
140 	.macro	fpu_restore_16odd thread
141 	.set	push
142 	.set	mips64r2
143 	SET_HARDFLOAT
144 	ldc1	$f1,  THREAD_FPR1(\thread)
145 	ldc1	$f3,  THREAD_FPR3(\thread)
146 	ldc1	$f5,  THREAD_FPR5(\thread)
147 	ldc1	$f7,  THREAD_FPR7(\thread)
148 	ldc1	$f9,  THREAD_FPR9(\thread)
149 	ldc1	$f11, THREAD_FPR11(\thread)
150 	ldc1	$f13, THREAD_FPR13(\thread)
151 	ldc1	$f15, THREAD_FPR15(\thread)
152 	ldc1	$f17, THREAD_FPR17(\thread)
153 	ldc1	$f19, THREAD_FPR19(\thread)
154 	ldc1	$f21, THREAD_FPR21(\thread)
155 	ldc1	$f23, THREAD_FPR23(\thread)
156 	ldc1	$f25, THREAD_FPR25(\thread)
157 	ldc1	$f27, THREAD_FPR27(\thread)
158 	ldc1	$f29, THREAD_FPR29(\thread)
159 	ldc1	$f31, THREAD_FPR31(\thread)
160 	.set	pop
161 	.endm
162 
163 	.macro	fpu_restore_double thread status tmp
164 #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \
165 		defined(CONFIG_CPU_MIPS32_R6)
166 	sll	\tmp, \status, 5
167 	bgez	\tmp, 10f				# 16 register mode?
168 
169 	fpu_restore_16odd \thread
170 10:
171 #endif
172 	fpu_restore_16even \thread \tmp
173 	.endm
174 
175 #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
176 	.macro	_EXT	rd, rs, p, s
177 	ext	\rd, \rs, \p, \s
178 	.endm
179 #else /* !CONFIG_CPU_MIPSR2 || !CONFIG_CPU_MIPSR6 */
180 	.macro	_EXT	rd, rs, p, s
181 	srl	\rd, \rs, \p
182 	andi	\rd, \rd, (1 << \s) - 1
183 	.endm
184 #endif /* !CONFIG_CPU_MIPSR2 || !CONFIG_CPU_MIPSR6 */
185 
186 /*
187  * Temporary until all gas have MT ASE support
188  */
189 	.macro	DMT	reg=0
190 	.word	0x41600bc1 | (\reg << 16)
191 	.endm
192 
193 	.macro	EMT	reg=0
194 	.word	0x41600be1 | (\reg << 16)
195 	.endm
196 
197 	.macro	DVPE	reg=0
198 	.word	0x41600001 | (\reg << 16)
199 	.endm
200 
201 	.macro	EVPE	reg=0
202 	.word	0x41600021 | (\reg << 16)
203 	.endm
204 
205 	.macro	MFTR	rt=0, rd=0, u=0, sel=0
206 	 .word	0x41000000 | (\rt << 16) | (\rd << 11) | (\u << 5) | (\sel)
207 	.endm
208 
209 	.macro	MTTR	rt=0, rd=0, u=0, sel=0
210 	 .word	0x41800000 | (\rt << 16) | (\rd << 11) | (\u << 5) | (\sel)
211 	.endm
212 
213 #ifdef TOOLCHAIN_SUPPORTS_MSA
214 	.macro	_cfcmsa	rd, cs
215 	.set	push
216 	.set	mips32r2
217 	.set	msa
218 	cfcmsa	\rd, $\cs
219 	.set	pop
220 	.endm
221 
222 	.macro	_ctcmsa	cd, rs
223 	.set	push
224 	.set	mips32r2
225 	.set	msa
226 	ctcmsa	$\cd, \rs
227 	.set	pop
228 	.endm
229 
230 	.macro	ld_d	wd, off, base
231 	.set	push
232 	.set	mips32r2
233 	.set	msa
234 	ld.d	$w\wd, \off(\base)
235 	.set	pop
236 	.endm
237 
238 	.macro	st_d	wd, off, base
239 	.set	push
240 	.set	mips32r2
241 	.set	msa
242 	st.d	$w\wd, \off(\base)
243 	.set	pop
244 	.endm
245 
246 	.macro	copy_u_w	ws, n
247 	.set	push
248 	.set	mips32r2
249 	.set	msa
250 	copy_u.w $1, $w\ws[\n]
251 	.set	pop
252 	.endm
253 
254 	.macro	copy_u_d	ws, n
255 	.set	push
256 	.set	mips64r2
257 	.set	msa
258 	copy_u.d $1, $w\ws[\n]
259 	.set	pop
260 	.endm
261 
262 	.macro	insert_w	wd, n
263 	.set	push
264 	.set	mips32r2
265 	.set	msa
266 	insert.w $w\wd[\n], $1
267 	.set	pop
268 	.endm
269 
270 	.macro	insert_d	wd, n
271 	.set	push
272 	.set	mips64r2
273 	.set	msa
274 	insert.d $w\wd[\n], $1
275 	.set	pop
276 	.endm
277 #else
278 
279 #ifdef CONFIG_CPU_MICROMIPS
280 #define CFC_MSA_INSN		0x587e0056
281 #define CTC_MSA_INSN		0x583e0816
282 #define LDD_MSA_INSN		0x58000837
283 #define STD_MSA_INSN		0x5800083f
284 #define COPY_UW_MSA_INSN	0x58f00056
285 #define COPY_UD_MSA_INSN	0x58f80056
286 #define INSERT_W_MSA_INSN	0x59300816
287 #define INSERT_D_MSA_INSN	0x59380816
288 #else
289 #define CFC_MSA_INSN		0x787e0059
290 #define CTC_MSA_INSN		0x783e0819
291 #define LDD_MSA_INSN		0x78000823
292 #define STD_MSA_INSN		0x78000827
293 #define COPY_UW_MSA_INSN	0x78f00059
294 #define COPY_UD_MSA_INSN	0x78f80059
295 #define INSERT_W_MSA_INSN	0x79300819
296 #define INSERT_D_MSA_INSN	0x79380819
297 #endif
298 
299 	/*
300 	 * Temporary until all toolchains in use include MSA support.
301 	 */
302 	.macro	_cfcmsa	rd, cs
303 	.set	push
304 	.set	noat
305 	SET_HARDFLOAT
306 	.insn
307 	.word	CFC_MSA_INSN | (\cs << 11)
308 	move	\rd, $1
309 	.set	pop
310 	.endm
311 
312 	.macro	_ctcmsa	cd, rs
313 	.set	push
314 	.set	noat
315 	SET_HARDFLOAT
316 	move	$1, \rs
317 	.word	CTC_MSA_INSN | (\cd << 6)
318 	.set	pop
319 	.endm
320 
321 	.macro	ld_d	wd, off, base
322 	.set	push
323 	.set	noat
324 	SET_HARDFLOAT
325 	addu	$1, \base, \off
326 	.word	LDD_MSA_INSN | (\wd << 6)
327 	.set	pop
328 	.endm
329 
330 	.macro	st_d	wd, off, base
331 	.set	push
332 	.set	noat
333 	SET_HARDFLOAT
334 	addu	$1, \base, \off
335 	.word	STD_MSA_INSN | (\wd << 6)
336 	.set	pop
337 	.endm
338 
339 	.macro	copy_u_w	ws, n
340 	.set	push
341 	.set	noat
342 	SET_HARDFLOAT
343 	.insn
344 	.word	COPY_UW_MSA_INSN | (\n << 16) | (\ws << 11)
345 	.set	pop
346 	.endm
347 
348 	.macro	copy_u_d	ws, n
349 	.set	push
350 	.set	noat
351 	SET_HARDFLOAT
352 	.insn
353 	.word	COPY_UD_MSA_INSN | (\n << 16) | (\ws << 11)
354 	.set	pop
355 	.endm
356 
357 	.macro	insert_w	wd, n
358 	.set	push
359 	.set	noat
360 	SET_HARDFLOAT
361 	.word	INSERT_W_MSA_INSN | (\n << 16) | (\wd << 6)
362 	.set	pop
363 	.endm
364 
365 	.macro	insert_d	wd, n
366 	.set	push
367 	.set	noat
368 	SET_HARDFLOAT
369 	.word	INSERT_D_MSA_INSN | (\n << 16) | (\wd << 6)
370 	.set	pop
371 	.endm
372 #endif
373 
374 	.macro	msa_save_all	thread
375 	st_d	0, THREAD_FPR0, \thread
376 	st_d	1, THREAD_FPR1, \thread
377 	st_d	2, THREAD_FPR2, \thread
378 	st_d	3, THREAD_FPR3, \thread
379 	st_d	4, THREAD_FPR4, \thread
380 	st_d	5, THREAD_FPR5, \thread
381 	st_d	6, THREAD_FPR6, \thread
382 	st_d	7, THREAD_FPR7, \thread
383 	st_d	8, THREAD_FPR8, \thread
384 	st_d	9, THREAD_FPR9, \thread
385 	st_d	10, THREAD_FPR10, \thread
386 	st_d	11, THREAD_FPR11, \thread
387 	st_d	12, THREAD_FPR12, \thread
388 	st_d	13, THREAD_FPR13, \thread
389 	st_d	14, THREAD_FPR14, \thread
390 	st_d	15, THREAD_FPR15, \thread
391 	st_d	16, THREAD_FPR16, \thread
392 	st_d	17, THREAD_FPR17, \thread
393 	st_d	18, THREAD_FPR18, \thread
394 	st_d	19, THREAD_FPR19, \thread
395 	st_d	20, THREAD_FPR20, \thread
396 	st_d	21, THREAD_FPR21, \thread
397 	st_d	22, THREAD_FPR22, \thread
398 	st_d	23, THREAD_FPR23, \thread
399 	st_d	24, THREAD_FPR24, \thread
400 	st_d	25, THREAD_FPR25, \thread
401 	st_d	26, THREAD_FPR26, \thread
402 	st_d	27, THREAD_FPR27, \thread
403 	st_d	28, THREAD_FPR28, \thread
404 	st_d	29, THREAD_FPR29, \thread
405 	st_d	30, THREAD_FPR30, \thread
406 	st_d	31, THREAD_FPR31, \thread
407 	.set	push
408 	.set	noat
409 	SET_HARDFLOAT
410 	_cfcmsa	$1, MSA_CSR
411 	sw	$1, THREAD_MSA_CSR(\thread)
412 	.set	pop
413 	.endm
414 
415 	.macro	msa_restore_all	thread
416 	.set	push
417 	.set	noat
418 	SET_HARDFLOAT
419 	lw	$1, THREAD_MSA_CSR(\thread)
420 	_ctcmsa	MSA_CSR, $1
421 	.set	pop
422 	ld_d	0, THREAD_FPR0, \thread
423 	ld_d	1, THREAD_FPR1, \thread
424 	ld_d	2, THREAD_FPR2, \thread
425 	ld_d	3, THREAD_FPR3, \thread
426 	ld_d	4, THREAD_FPR4, \thread
427 	ld_d	5, THREAD_FPR5, \thread
428 	ld_d	6, THREAD_FPR6, \thread
429 	ld_d	7, THREAD_FPR7, \thread
430 	ld_d	8, THREAD_FPR8, \thread
431 	ld_d	9, THREAD_FPR9, \thread
432 	ld_d	10, THREAD_FPR10, \thread
433 	ld_d	11, THREAD_FPR11, \thread
434 	ld_d	12, THREAD_FPR12, \thread
435 	ld_d	13, THREAD_FPR13, \thread
436 	ld_d	14, THREAD_FPR14, \thread
437 	ld_d	15, THREAD_FPR15, \thread
438 	ld_d	16, THREAD_FPR16, \thread
439 	ld_d	17, THREAD_FPR17, \thread
440 	ld_d	18, THREAD_FPR18, \thread
441 	ld_d	19, THREAD_FPR19, \thread
442 	ld_d	20, THREAD_FPR20, \thread
443 	ld_d	21, THREAD_FPR21, \thread
444 	ld_d	22, THREAD_FPR22, \thread
445 	ld_d	23, THREAD_FPR23, \thread
446 	ld_d	24, THREAD_FPR24, \thread
447 	ld_d	25, THREAD_FPR25, \thread
448 	ld_d	26, THREAD_FPR26, \thread
449 	ld_d	27, THREAD_FPR27, \thread
450 	ld_d	28, THREAD_FPR28, \thread
451 	ld_d	29, THREAD_FPR29, \thread
452 	ld_d	30, THREAD_FPR30, \thread
453 	ld_d	31, THREAD_FPR31, \thread
454 	.endm
455 
456 	.macro	msa_init_upper wd
457 #ifdef CONFIG_64BIT
458 	insert_d \wd, 1
459 #else
460 	insert_w \wd, 2
461 	insert_w \wd, 3
462 #endif
463 	.endm
464 
465 	.macro	msa_init_all_upper
466 	.set	push
467 	.set	noat
468 	SET_HARDFLOAT
469 	not	$1, zero
470 	msa_init_upper	0
471 	msa_init_upper	1
472 	msa_init_upper	2
473 	msa_init_upper	3
474 	msa_init_upper	4
475 	msa_init_upper	5
476 	msa_init_upper	6
477 	msa_init_upper	7
478 	msa_init_upper	8
479 	msa_init_upper	9
480 	msa_init_upper	10
481 	msa_init_upper	11
482 	msa_init_upper	12
483 	msa_init_upper	13
484 	msa_init_upper	14
485 	msa_init_upper	15
486 	msa_init_upper	16
487 	msa_init_upper	17
488 	msa_init_upper	18
489 	msa_init_upper	19
490 	msa_init_upper	20
491 	msa_init_upper	21
492 	msa_init_upper	22
493 	msa_init_upper	23
494 	msa_init_upper	24
495 	msa_init_upper	25
496 	msa_init_upper	26
497 	msa_init_upper	27
498 	msa_init_upper	28
499 	msa_init_upper	29
500 	msa_init_upper	30
501 	msa_init_upper	31
502 	.set	pop
503 	.endm
504 
505 #endif /* _ASM_ASMMACRO_H */
506