• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 	.set	pop
139 	.endm
140 
141 	.macro	fpu_restore_16odd thread
142 	.set	push
143 	.set	mips64r2
144 	SET_HARDFLOAT
145 	ldc1	$f1,  THREAD_FPR1(\thread)
146 	ldc1	$f3,  THREAD_FPR3(\thread)
147 	ldc1	$f5,  THREAD_FPR5(\thread)
148 	ldc1	$f7,  THREAD_FPR7(\thread)
149 	ldc1	$f9,  THREAD_FPR9(\thread)
150 	ldc1	$f11, THREAD_FPR11(\thread)
151 	ldc1	$f13, THREAD_FPR13(\thread)
152 	ldc1	$f15, THREAD_FPR15(\thread)
153 	ldc1	$f17, THREAD_FPR17(\thread)
154 	ldc1	$f19, THREAD_FPR19(\thread)
155 	ldc1	$f21, THREAD_FPR21(\thread)
156 	ldc1	$f23, THREAD_FPR23(\thread)
157 	ldc1	$f25, THREAD_FPR25(\thread)
158 	ldc1	$f27, THREAD_FPR27(\thread)
159 	ldc1	$f29, THREAD_FPR29(\thread)
160 	ldc1	$f31, THREAD_FPR31(\thread)
161 	.set	pop
162 	.endm
163 
164 	.macro	fpu_restore_double thread status tmp
165 #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \
166 		defined(CONFIG_CPU_MIPS32_R6)
167 	sll	\tmp, \status, 5
168 	bgez	\tmp, 10f				# 16 register mode?
169 
170 	fpu_restore_16odd \thread
171 10:
172 #endif
173 	fpu_restore_16even \thread \tmp
174 	.endm
175 
176 #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
177 	.macro	_EXT	rd, rs, p, s
178 	ext	\rd, \rs, \p, \s
179 	.endm
180 #else /* !CONFIG_CPU_MIPSR2 || !CONFIG_CPU_MIPSR6 */
181 	.macro	_EXT	rd, rs, p, s
182 	srl	\rd, \rs, \p
183 	andi	\rd, \rd, (1 << \s) - 1
184 	.endm
185 #endif /* !CONFIG_CPU_MIPSR2 || !CONFIG_CPU_MIPSR6 */
186 
187 /*
188  * Temporary until all gas have MT ASE support
189  */
190 	.macro	DMT	reg=0
191 	.word	0x41600bc1 | (\reg << 16)
192 	.endm
193 
194 	.macro	EMT	reg=0
195 	.word	0x41600be1 | (\reg << 16)
196 	.endm
197 
198 	.macro	DVPE	reg=0
199 	.word	0x41600001 | (\reg << 16)
200 	.endm
201 
202 	.macro	EVPE	reg=0
203 	.word	0x41600021 | (\reg << 16)
204 	.endm
205 
206 	.macro	MFTR	rt=0, rd=0, u=0, sel=0
207 	 .word	0x41000000 | (\rt << 16) | (\rd << 11) | (\u << 5) | (\sel)
208 	.endm
209 
210 	.macro	MTTR	rt=0, rd=0, u=0, sel=0
211 	 .word	0x41800000 | (\rt << 16) | (\rd << 11) | (\u << 5) | (\sel)
212 	.endm
213 
214 #ifdef TOOLCHAIN_SUPPORTS_MSA
215 /* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */
216 #undef fp
217 
218 	.macro	_cfcmsa	rd, cs
219 	.set	push
220 	.set	mips32r2
221 	.set	fp=64
222 	.set	msa
223 	cfcmsa	\rd, $\cs
224 	.set	pop
225 	.endm
226 
227 	.macro	_ctcmsa	cd, rs
228 	.set	push
229 	.set	mips32r2
230 	.set	fp=64
231 	.set	msa
232 	ctcmsa	$\cd, \rs
233 	.set	pop
234 	.endm
235 
236 	.macro	ld_b	wd, off, base
237 	.set	push
238 	.set	mips32r2
239 	.set	msa
240 	ld.b	$w\wd, \off(\base)
241 	.set	pop
242 	.endm
243 
244 	.macro	ld_h	wd, off, base
245 	.set	push
246 	.set	mips32r2
247 	.set	msa
248 	ld.h	$w\wd, \off(\base)
249 	.set	pop
250 	.endm
251 
252 	.macro	ld_w	wd, off, base
253 	.set	push
254 	.set	mips32r2
255 	.set	msa
256 	ld.w	$w\wd, \off(\base)
257 	.set	pop
258 	.endm
259 
260 	.macro	ld_d	wd, off, base
261 	.set	push
262 	.set	mips32r2
263 	.set	fp=64
264 	.set	msa
265 	ld.d	$w\wd, \off(\base)
266 	.set	pop
267 	.endm
268 
269 	.macro	st_b	wd, off, base
270 	.set	push
271 	.set	mips32r2
272 	.set	msa
273 	st.b	$w\wd, \off(\base)
274 	.set	pop
275 	.endm
276 
277 	.macro	st_h	wd, off, base
278 	.set	push
279 	.set	mips32r2
280 	.set	msa
281 	st.h	$w\wd, \off(\base)
282 	.set	pop
283 	.endm
284 
285 	.macro	st_w	wd, off, base
286 	.set	push
287 	.set	mips32r2
288 	.set	msa
289 	st.w	$w\wd, \off(\base)
290 	.set	pop
291 	.endm
292 
293 	.macro	st_d	wd, off, base
294 	.set	push
295 	.set	mips32r2
296 	.set	fp=64
297 	.set	msa
298 	st.d	$w\wd, \off(\base)
299 	.set	pop
300 	.endm
301 
302 	.macro	copy_u_w	ws, n
303 	.set	push
304 	.set	mips32r2
305 	.set	fp=64
306 	.set	msa
307 	copy_u.w $1, $w\ws[\n]
308 	.set	pop
309 	.endm
310 
311 	.macro	copy_u_d	ws, n
312 	.set	push
313 	.set	mips64r2
314 	.set	fp=64
315 	.set	msa
316 	copy_u.d $1, $w\ws[\n]
317 	.set	pop
318 	.endm
319 
320 	.macro	insert_w	wd, n
321 	.set	push
322 	.set	mips32r2
323 	.set	fp=64
324 	.set	msa
325 	insert.w $w\wd[\n], $1
326 	.set	pop
327 	.endm
328 
329 	.macro	insert_d	wd, n
330 	.set	push
331 	.set	mips64r2
332 	.set	fp=64
333 	.set	msa
334 	insert.d $w\wd[\n], $1
335 	.set	pop
336 	.endm
337 #else
338 
339 #ifdef CONFIG_CPU_MICROMIPS
340 #define CFC_MSA_INSN		0x587e0056
341 #define CTC_MSA_INSN		0x583e0816
342 #define LDB_MSA_INSN		0x58000807
343 #define LDH_MSA_INSN		0x58000817
344 #define LDW_MSA_INSN		0x58000827
345 #define LDD_MSA_INSN		0x58000837
346 #define STB_MSA_INSN		0x5800080f
347 #define STH_MSA_INSN		0x5800081f
348 #define STW_MSA_INSN		0x5800082f
349 #define STD_MSA_INSN		0x5800083f
350 #define COPY_UW_MSA_INSN	0x58f00056
351 #define COPY_UD_MSA_INSN	0x58f80056
352 #define INSERT_W_MSA_INSN	0x59300816
353 #define INSERT_D_MSA_INSN	0x59380816
354 #else
355 #define CFC_MSA_INSN		0x787e0059
356 #define CTC_MSA_INSN		0x783e0819
357 #define LDB_MSA_INSN		0x78000820
358 #define LDH_MSA_INSN		0x78000821
359 #define LDW_MSA_INSN		0x78000822
360 #define LDD_MSA_INSN		0x78000823
361 #define STB_MSA_INSN		0x78000824
362 #define STH_MSA_INSN		0x78000825
363 #define STW_MSA_INSN		0x78000826
364 #define STD_MSA_INSN		0x78000827
365 #define COPY_UW_MSA_INSN	0x78f00059
366 #define COPY_UD_MSA_INSN	0x78f80059
367 #define INSERT_W_MSA_INSN	0x79300819
368 #define INSERT_D_MSA_INSN	0x79380819
369 #endif
370 
371 	/*
372 	 * Temporary until all toolchains in use include MSA support.
373 	 */
374 	.macro	_cfcmsa	rd, cs
375 	.set	push
376 	.set	noat
377 	SET_HARDFLOAT
378 	.insn
379 	.word	CFC_MSA_INSN | (\cs << 11)
380 	move	\rd, $1
381 	.set	pop
382 	.endm
383 
384 	.macro	_ctcmsa	cd, rs
385 	.set	push
386 	.set	noat
387 	SET_HARDFLOAT
388 	move	$1, \rs
389 	.word	CTC_MSA_INSN | (\cd << 6)
390 	.set	pop
391 	.endm
392 
393 	.macro	ld_b	wd, off, base
394 	.set	push
395 	.set	noat
396 	SET_HARDFLOAT
397 	addu	$1, \base, \off
398 	.word	LDB_MSA_INSN | (\wd << 6)
399 	.set	pop
400 	.endm
401 
402 	.macro	ld_h	wd, off, base
403 	.set	push
404 	.set	noat
405 	SET_HARDFLOAT
406 	addu	$1, \base, \off
407 	.word	LDH_MSA_INSN | (\wd << 6)
408 	.set	pop
409 	.endm
410 
411 	.macro	ld_w	wd, off, base
412 	.set	push
413 	.set	noat
414 	SET_HARDFLOAT
415 	addu	$1, \base, \off
416 	.word	LDW_MSA_INSN | (\wd << 6)
417 	.set	pop
418 	.endm
419 
420 	.macro	ld_d	wd, off, base
421 	.set	push
422 	.set	noat
423 	SET_HARDFLOAT
424 	addu	$1, \base, \off
425 	.word	LDD_MSA_INSN | (\wd << 6)
426 	.set	pop
427 	.endm
428 
429 	.macro	st_b	wd, off, base
430 	.set	push
431 	.set	noat
432 	SET_HARDFLOAT
433 	addu	$1, \base, \off
434 	.word	STB_MSA_INSN | (\wd << 6)
435 	.set	pop
436 	.endm
437 
438 	.macro	st_h	wd, off, base
439 	.set	push
440 	.set	noat
441 	SET_HARDFLOAT
442 	addu	$1, \base, \off
443 	.word	STH_MSA_INSN | (\wd << 6)
444 	.set	pop
445 	.endm
446 
447 	.macro	st_w	wd, off, base
448 	.set	push
449 	.set	noat
450 	SET_HARDFLOAT
451 	addu	$1, \base, \off
452 	.word	STW_MSA_INSN | (\wd << 6)
453 	.set	pop
454 	.endm
455 
456 	.macro	st_d	wd, off, base
457 	.set	push
458 	.set	noat
459 	SET_HARDFLOAT
460 	addu	$1, \base, \off
461 	.word	STD_MSA_INSN | (\wd << 6)
462 	.set	pop
463 	.endm
464 
465 	.macro	copy_u_w	ws, n
466 	.set	push
467 	.set	noat
468 	SET_HARDFLOAT
469 	.insn
470 	.word	COPY_UW_MSA_INSN | (\n << 16) | (\ws << 11)
471 	.set	pop
472 	.endm
473 
474 	.macro	copy_u_d	ws, n
475 	.set	push
476 	.set	noat
477 	SET_HARDFLOAT
478 	.insn
479 	.word	COPY_UD_MSA_INSN | (\n << 16) | (\ws << 11)
480 	.set	pop
481 	.endm
482 
483 	.macro	insert_w	wd, n
484 	.set	push
485 	.set	noat
486 	SET_HARDFLOAT
487 	.word	INSERT_W_MSA_INSN | (\n << 16) | (\wd << 6)
488 	.set	pop
489 	.endm
490 
491 	.macro	insert_d	wd, n
492 	.set	push
493 	.set	noat
494 	SET_HARDFLOAT
495 	.word	INSERT_D_MSA_INSN | (\n << 16) | (\wd << 6)
496 	.set	pop
497 	.endm
498 #endif
499 
500 	.macro	msa_save_all	thread
501 	st_d	0, THREAD_FPR0, \thread
502 	st_d	1, THREAD_FPR1, \thread
503 	st_d	2, THREAD_FPR2, \thread
504 	st_d	3, THREAD_FPR3, \thread
505 	st_d	4, THREAD_FPR4, \thread
506 	st_d	5, THREAD_FPR5, \thread
507 	st_d	6, THREAD_FPR6, \thread
508 	st_d	7, THREAD_FPR7, \thread
509 	st_d	8, THREAD_FPR8, \thread
510 	st_d	9, THREAD_FPR9, \thread
511 	st_d	10, THREAD_FPR10, \thread
512 	st_d	11, THREAD_FPR11, \thread
513 	st_d	12, THREAD_FPR12, \thread
514 	st_d	13, THREAD_FPR13, \thread
515 	st_d	14, THREAD_FPR14, \thread
516 	st_d	15, THREAD_FPR15, \thread
517 	st_d	16, THREAD_FPR16, \thread
518 	st_d	17, THREAD_FPR17, \thread
519 	st_d	18, THREAD_FPR18, \thread
520 	st_d	19, THREAD_FPR19, \thread
521 	st_d	20, THREAD_FPR20, \thread
522 	st_d	21, THREAD_FPR21, \thread
523 	st_d	22, THREAD_FPR22, \thread
524 	st_d	23, THREAD_FPR23, \thread
525 	st_d	24, THREAD_FPR24, \thread
526 	st_d	25, THREAD_FPR25, \thread
527 	st_d	26, THREAD_FPR26, \thread
528 	st_d	27, THREAD_FPR27, \thread
529 	st_d	28, THREAD_FPR28, \thread
530 	st_d	29, THREAD_FPR29, \thread
531 	st_d	30, THREAD_FPR30, \thread
532 	st_d	31, THREAD_FPR31, \thread
533 	.set	push
534 	.set	noat
535 	SET_HARDFLOAT
536 	_cfcmsa	$1, MSA_CSR
537 	sw	$1, THREAD_MSA_CSR(\thread)
538 	.set	pop
539 	.endm
540 
541 	.macro	msa_restore_all	thread
542 	.set	push
543 	.set	noat
544 	SET_HARDFLOAT
545 	lw	$1, THREAD_MSA_CSR(\thread)
546 	_ctcmsa	MSA_CSR, $1
547 	.set	pop
548 	ld_d	0, THREAD_FPR0, \thread
549 	ld_d	1, THREAD_FPR1, \thread
550 	ld_d	2, THREAD_FPR2, \thread
551 	ld_d	3, THREAD_FPR3, \thread
552 	ld_d	4, THREAD_FPR4, \thread
553 	ld_d	5, THREAD_FPR5, \thread
554 	ld_d	6, THREAD_FPR6, \thread
555 	ld_d	7, THREAD_FPR7, \thread
556 	ld_d	8, THREAD_FPR8, \thread
557 	ld_d	9, THREAD_FPR9, \thread
558 	ld_d	10, THREAD_FPR10, \thread
559 	ld_d	11, THREAD_FPR11, \thread
560 	ld_d	12, THREAD_FPR12, \thread
561 	ld_d	13, THREAD_FPR13, \thread
562 	ld_d	14, THREAD_FPR14, \thread
563 	ld_d	15, THREAD_FPR15, \thread
564 	ld_d	16, THREAD_FPR16, \thread
565 	ld_d	17, THREAD_FPR17, \thread
566 	ld_d	18, THREAD_FPR18, \thread
567 	ld_d	19, THREAD_FPR19, \thread
568 	ld_d	20, THREAD_FPR20, \thread
569 	ld_d	21, THREAD_FPR21, \thread
570 	ld_d	22, THREAD_FPR22, \thread
571 	ld_d	23, THREAD_FPR23, \thread
572 	ld_d	24, THREAD_FPR24, \thread
573 	ld_d	25, THREAD_FPR25, \thread
574 	ld_d	26, THREAD_FPR26, \thread
575 	ld_d	27, THREAD_FPR27, \thread
576 	ld_d	28, THREAD_FPR28, \thread
577 	ld_d	29, THREAD_FPR29, \thread
578 	ld_d	30, THREAD_FPR30, \thread
579 	ld_d	31, THREAD_FPR31, \thread
580 	.endm
581 
582 	.macro	msa_init_upper wd
583 #ifdef CONFIG_64BIT
584 	insert_d \wd, 1
585 #else
586 	insert_w \wd, 2
587 	insert_w \wd, 3
588 #endif
589 	.endm
590 
591 	.macro	msa_init_all_upper
592 	.set	push
593 	.set	noat
594 	SET_HARDFLOAT
595 	not	$1, zero
596 	msa_init_upper	0
597 	msa_init_upper	1
598 	msa_init_upper	2
599 	msa_init_upper	3
600 	msa_init_upper	4
601 	msa_init_upper	5
602 	msa_init_upper	6
603 	msa_init_upper	7
604 	msa_init_upper	8
605 	msa_init_upper	9
606 	msa_init_upper	10
607 	msa_init_upper	11
608 	msa_init_upper	12
609 	msa_init_upper	13
610 	msa_init_upper	14
611 	msa_init_upper	15
612 	msa_init_upper	16
613 	msa_init_upper	17
614 	msa_init_upper	18
615 	msa_init_upper	19
616 	msa_init_upper	20
617 	msa_init_upper	21
618 	msa_init_upper	22
619 	msa_init_upper	23
620 	msa_init_upper	24
621 	msa_init_upper	25
622 	msa_init_upper	26
623 	msa_init_upper	27
624 	msa_init_upper	28
625 	msa_init_upper	29
626 	msa_init_upper	30
627 	msa_init_upper	31
628 	.set	pop
629 	.endm
630 
631 #endif /* _ASM_ASMMACRO_H */
632