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