1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (C) 2020 Loongson Technology Corporation Limited
4 */
5#ifndef _ASM_ASMMACRO_H
6#define _ASM_ASMMACRO_H
7
8#include <asm/asm-offsets.h>
9
10#ifdef CONFIG_32BIT
11#include <asm/asmmacro-32.h>
12#endif
13#ifdef CONFIG_64BIT
14#include <asm/asmmacro-64.h>
15#endif
16
17	.macro	parse_v var val
18	\var	= \val
19	.endm
20
21	.macro	parse_r var r
22	\var	= -1
23	.ifc	\r, $r0
24	\var	= 0
25	.endif
26	.ifc	\r, $r1
27	\var	= 1
28	.endif
29	.ifc	\r, $r2
30	\var	= 2
31	.endif
32	.ifc	\r, $r3
33	\var	= 3
34	.endif
35	.ifc	\r, $r4
36	\var	= 4
37	.endif
38	.ifc	\r, $r5
39	\var	= 5
40	.endif
41	.ifc	\r, $r6
42	\var	= 6
43	.endif
44	.ifc	\r, $r7
45	\var	= 7
46	.endif
47	.ifc	\r, $r8
48	\var	= 8
49	.endif
50	.ifc	\r, $r9
51	\var	= 9
52	.endif
53	.ifc	\r, $r10
54	\var	= 10
55	.endif
56	.ifc	\r, $r11
57	\var	= 11
58	.endif
59	.ifc	\r, $r12
60	\var	= 12
61	.endif
62	.ifc	\r, $r13
63	\var	= 13
64	.endif
65	.ifc	\r, $r14
66	\var	= 14
67	.endif
68	.ifc	\r, $r15
69	\var	= 15
70	.endif
71	.ifc	\r, $r16
72	\var	= 16
73	.endif
74	.ifc	\r, $r17
75	\var	= 17
76	.endif
77	.ifc	\r, $r18
78	\var	= 18
79	.endif
80	.ifc	\r, $r19
81	\var	= 19
82	.endif
83	.ifc	\r, $r20
84	\var	= 20
85	.endif
86	.ifc	\r, $r21
87	\var	= 21
88	.endif
89	.ifc	\r, $r22
90	\var	= 22
91	.endif
92	.ifc	\r, $r23
93	\var	= 23
94	.endif
95	.ifc	\r, $r24
96	\var	= 24
97	.endif
98	.ifc	\r, $r25
99	\var	= 25
100	.endif
101	.ifc	\r, $r26
102	\var	= 26
103	.endif
104	.ifc	\r, $r27
105	\var	= 27
106	.endif
107	.ifc	\r, $r28
108	\var	= 28
109	.endif
110	.ifc	\r, $r29
111	\var	= 29
112	.endif
113	.ifc	\r, $r30
114	\var	= 30
115	.endif
116	.ifc	\r, $r31
117	\var	= 31
118	.endif
119	.iflt	\var
120	.error	"Unable to parse register name \r"
121	.endif
122	.endm
123
124	.macro	parse_vr var vr
125	\var	= -1
126	.ifc	\vr, $vr0
127	\var	= 0
128	.endif
129	.ifc	\vr, $vr1
130	\var	= 1
131	.endif
132	.ifc	\vr, $vr2
133	\var	= 2
134	.endif
135	.ifc	\vr, $vr3
136	\var	= 3
137	.endif
138	.ifc	\vr, $vr4
139	\var	= 4
140	.endif
141	.ifc	\vr, $vr5
142	\var	= 5
143	.endif
144	.ifc	\vr, $vr6
145	\var	= 6
146	.endif
147	.ifc	\vr, $vr7
148	\var	= 7
149	.endif
150	.ifc	\vr, $vr8
151	\var	= 8
152	.endif
153	.ifc	\vr, $vr9
154	\var	= 9
155	.endif
156	.ifc	\vr, $vr10
157	\var	= 10
158	.endif
159	.ifc	\vr, $vr11
160	\var	= 11
161	.endif
162	.ifc	\vr, $vr12
163	\var	= 12
164	.endif
165	.ifc	\vr, $vr13
166	\var	= 13
167	.endif
168	.ifc	\vr, $vr14
169	\var	= 14
170	.endif
171	.ifc	\vr, $vr15
172	\var	= 15
173	.endif
174	.ifc	\vr, $vr16
175	\var	= 16
176	.endif
177	.ifc	\vr, $vr17
178	\var	= 17
179	.endif
180	.ifc	\vr, $vr18
181	\var	= 18
182	.endif
183	.ifc	\vr, $vr19
184	\var	= 19
185	.endif
186	.ifc	\vr, $vr20
187	\var	= 20
188	.endif
189	.ifc	\vr, $vr21
190	\var	= 21
191	.endif
192	.ifc	\vr, $vr22
193	\var	= 22
194	.endif
195	.ifc	\vr, $vr23
196	\var	= 23
197	.endif
198	.ifc	\vr, $vr24
199	\var	= 24
200	.endif
201	.ifc	\vr, $vr25
202	\var	= 25
203	.endif
204	.ifc	\vr, $vr26
205	\var	= 26
206	.endif
207	.ifc	\vr, $vr27
208	\var	= 27
209	.endif
210	.ifc	\vr, $vr28
211	\var	= 28
212	.endif
213	.ifc	\vr, $vr29
214	\var	= 29
215	.endif
216	.ifc	\vr, $vr30
217	\var	= 30
218	.endif
219	.ifc	\vr, $vr31
220	\var	= 31
221	.endif
222	.iflt	\var
223	.error	"Unable to parse register name \r"
224	.endif
225	.endm
226
227	.macro	parse_xr var xr
228	\var	= -1
229	.ifc	\xr, $xr0
230	\var	= 0
231	.endif
232	.ifc	\xr, $xr1
233	\var	= 1
234	.endif
235	.ifc	\xr, $xr2
236	\var	= 2
237	.endif
238	.ifc	\xr, $xr3
239	\var	= 3
240	.endif
241	.ifc	\xr, $xr4
242	\var	= 4
243	.endif
244	.ifc	\xr, $xr5
245	\var	= 5
246	.endif
247	.ifc	\xr, $xr6
248	\var	= 6
249	.endif
250	.ifc	\xr, $xr7
251	\var	= 7
252	.endif
253	.ifc	\xr, $xr8
254	\var	= 8
255	.endif
256	.ifc	\xr, $xr9
257	\var	= 9
258	.endif
259	.ifc	\xr, $xr10
260	\var	= 10
261	.endif
262	.ifc	\xr, $xr11
263	\var	= 11
264	.endif
265	.ifc	\xr, $xr12
266	\var	= 12
267	.endif
268	.ifc	\xr, $xr13
269	\var	= 13
270	.endif
271	.ifc	\xr, $xr14
272	\var	= 14
273	.endif
274	.ifc	\xr, $xr15
275	\var	= 15
276	.endif
277	.ifc	\xr, $xr16
278	\var	= 16
279	.endif
280	.ifc	\xr, $xr17
281	\var	= 17
282	.endif
283	.ifc	\xr, $xr18
284	\var	= 18
285	.endif
286	.ifc	\xr, $xr19
287	\var	= 19
288	.endif
289	.ifc	\xr, $xr20
290	\var	= 20
291	.endif
292	.ifc	\xr, $xr21
293	\var	= 21
294	.endif
295	.ifc	\xr, $xr22
296	\var	= 22
297	.endif
298	.ifc	\xr, $xr23
299	\var	= 23
300	.endif
301	.ifc	\xr, $xr24
302	\var	= 24
303	.endif
304	.ifc	\xr, $xr25
305	\var	= 25
306	.endif
307	.ifc	\xr, $xr26
308	\var	= 26
309	.endif
310	.ifc	\xr, $xr27
311	\var	= 27
312	.endif
313	.ifc	\xr, $xr28
314	\var	= 28
315	.endif
316	.ifc	\xr, $xr29
317	\var	= 29
318	.endif
319	.ifc	\xr, $xr30
320	\var	= 30
321	.endif
322	.ifc	\xr, $xr31
323	\var	= 31
324	.endif
325	.iflt	\var
326	.error	"Unable to parse register name \r"
327	.endif
328	.endm
329
330	.macro fpu_save_csr thread tmp
331	movfcsr2gr	\tmp, fcsr0
332	stptr.w	\tmp, \thread, THREAD_FCSR
333#ifdef CONFIG_CPU_HAS_LBT
334	/* TM bit is always 0 if LBT not supported */
335	andi	\tmp, \tmp, FPU_CSR_TM
336	beqz	\tmp, 1f
337	bstrins.d \tmp, zero, FPU_CSR_TM_SHIFT, FPU_CSR_TM_SHIFT
338	movgr2fcsr      fcsr0, \tmp
339	x86mftop \tmp
340	stptr.d	\tmp, \thread, THREAD_FTOP
3411:
342#endif
343	.endm
344
345	.macro fpu_restore_csr thread tmp
346	ldptr.w	\tmp, \thread, THREAD_FCSR
347	movgr2fcsr	fcsr0, \tmp
348#ifdef CONFIG_CPU_HAS_LBT
349	/* TM bit is always 0 if LBT not supported */
350	andi	\tmp, \tmp, FPU_CSR_TM
351	beqz	\tmp, 1f
352	ldptr.d	\tmp, \thread, THREAD_FTOP
353	x86mttop 0x0
354	beq	\tmp, zero, 1f
355	addi.d	\tmp, \tmp, -1
356	x86mttop 0x1
357	beq	\tmp, zero, 1f
358	addi.d	\tmp, \tmp, -1
359	x86mttop 0x2
360	beq	\tmp, zero, 1f
361	addi.d	\tmp, \tmp, -1
362	x86mttop 0x3
363	beq	\tmp, zero, 1f
364	addi.d	\tmp, \tmp, -1
365	x86mttop 0x4
366	beq	\tmp, zero, 1f
367	addi.d	\tmp, \tmp, -1
368	x86mttop 0x5
369	beq	\tmp, zero, 1f
370	addi.d	\tmp, \tmp, -1
371	x86mttop 0x6
372	beq	\tmp, zero, 1f
373	addi.d	\tmp, \tmp, -1
374	x86mttop 0x7
3751:
376#endif
377	.endm
378
379	.macro fpu_save_cc thread tmp0 tmp1
380	movcf2gr	\tmp0, $fcc0
381	move	\tmp1, \tmp0
382	movcf2gr	\tmp0, $fcc1
383	bstrins.d	\tmp1, \tmp0, 15, 8
384	movcf2gr	\tmp0, $fcc2
385	bstrins.d	\tmp1, \tmp0, 23, 16
386	movcf2gr	\tmp0, $fcc3
387	bstrins.d	\tmp1, \tmp0, 31, 24
388	movcf2gr	\tmp0, $fcc4
389	bstrins.d	\tmp1, \tmp0, 39, 32
390	movcf2gr	\tmp0, $fcc5
391	bstrins.d	\tmp1, \tmp0, 47, 40
392	movcf2gr	\tmp0, $fcc6
393	bstrins.d	\tmp1, \tmp0, 55, 48
394	movcf2gr	\tmp0, $fcc7
395	bstrins.d	\tmp1, \tmp0, 63, 56
396	stptr.d		\tmp1, \thread, THREAD_FCC
397	.endm
398
399	.macro fpu_restore_cc thread tmp0 tmp1
400	ldptr.d	\tmp0, \thread, THREAD_FCC
401	bstrpick.d	\tmp1, \tmp0, 7, 0
402	movgr2cf	$fcc0, \tmp1
403	bstrpick.d	\tmp1, \tmp0, 15, 8
404	movgr2cf	$fcc1, \tmp1
405	bstrpick.d	\tmp1, \tmp0, 23, 16
406	movgr2cf	$fcc2, \tmp1
407	bstrpick.d	\tmp1, \tmp0, 31, 24
408	movgr2cf	$fcc3, \tmp1
409	bstrpick.d	\tmp1, \tmp0, 39, 32
410	movgr2cf	$fcc4, \tmp1
411	bstrpick.d	\tmp1, \tmp0, 47, 40
412	movgr2cf	$fcc5, \tmp1
413	bstrpick.d	\tmp1, \tmp0, 55, 48
414	movgr2cf	$fcc6, \tmp1
415	bstrpick.d	\tmp1, \tmp0, 63, 56
416	movgr2cf	$fcc7, \tmp1
417	.endm
418
419	.macro	fpu_save_double thread tmp
420	li.w	\tmp, THREAD_FPR0
421	PTR_ADD \tmp, \tmp, \thread
422	fst.d	$f0, \tmp, THREAD_FPR0  - THREAD_FPR0
423	fst.d	$f1, \tmp, THREAD_FPR1  - THREAD_FPR0
424	fst.d	$f2, \tmp, THREAD_FPR2  - THREAD_FPR0
425	fst.d	$f3, \tmp, THREAD_FPR3  - THREAD_FPR0
426	fst.d	$f4, \tmp, THREAD_FPR4  - THREAD_FPR0
427	fst.d	$f5, \tmp, THREAD_FPR5  - THREAD_FPR0
428	fst.d	$f6, \tmp, THREAD_FPR6  - THREAD_FPR0
429	fst.d	$f7, \tmp, THREAD_FPR7  - THREAD_FPR0
430	fst.d	$f8, \tmp, THREAD_FPR8  - THREAD_FPR0
431	fst.d	$f9, \tmp, THREAD_FPR9  - THREAD_FPR0
432	fst.d	$f10, \tmp, THREAD_FPR10 - THREAD_FPR0
433	fst.d	$f11, \tmp, THREAD_FPR11 - THREAD_FPR0
434	fst.d	$f12, \tmp, THREAD_FPR12 - THREAD_FPR0
435	fst.d	$f13, \tmp, THREAD_FPR13 - THREAD_FPR0
436	fst.d	$f14, \tmp, THREAD_FPR14 - THREAD_FPR0
437	fst.d	$f15, \tmp, THREAD_FPR15 - THREAD_FPR0
438	fst.d	$f16, \tmp, THREAD_FPR16 - THREAD_FPR0
439	fst.d	$f17, \tmp, THREAD_FPR17 - THREAD_FPR0
440	fst.d	$f18, \tmp, THREAD_FPR18 - THREAD_FPR0
441	fst.d	$f19, \tmp, THREAD_FPR19 - THREAD_FPR0
442	fst.d	$f20, \tmp, THREAD_FPR20 - THREAD_FPR0
443	fst.d	$f21, \tmp, THREAD_FPR21 - THREAD_FPR0
444	fst.d	$f22, \tmp, THREAD_FPR22 - THREAD_FPR0
445	fst.d	$f23, \tmp, THREAD_FPR23 - THREAD_FPR0
446	fst.d	$f24, \tmp, THREAD_FPR24 - THREAD_FPR0
447	fst.d	$f25, \tmp, THREAD_FPR25 - THREAD_FPR0
448	fst.d	$f26, \tmp, THREAD_FPR26 - THREAD_FPR0
449	fst.d	$f27, \tmp, THREAD_FPR27 - THREAD_FPR0
450	fst.d	$f28, \tmp, THREAD_FPR28 - THREAD_FPR0
451	fst.d	$f29, \tmp, THREAD_FPR29 - THREAD_FPR0
452	fst.d	$f30, \tmp, THREAD_FPR30 - THREAD_FPR0
453	fst.d	$f31, \tmp, THREAD_FPR31 - THREAD_FPR0
454	.endm
455
456	.macro	fpu_restore_double thread tmp
457	li.w	\tmp, THREAD_FPR0
458	PTR_ADD \tmp, \tmp, \thread
459	fld.d	$f0, \tmp, THREAD_FPR0  - THREAD_FPR0
460	fld.d	$f1, \tmp, THREAD_FPR1  - THREAD_FPR0
461	fld.d	$f2, \tmp, THREAD_FPR2  - THREAD_FPR0
462	fld.d	$f3, \tmp, THREAD_FPR3  - THREAD_FPR0
463	fld.d	$f4, \tmp, THREAD_FPR4  - THREAD_FPR0
464	fld.d	$f5, \tmp, THREAD_FPR5  - THREAD_FPR0
465	fld.d	$f6, \tmp, THREAD_FPR6  - THREAD_FPR0
466	fld.d	$f7, \tmp, THREAD_FPR7  - THREAD_FPR0
467	fld.d	$f8, \tmp, THREAD_FPR8  - THREAD_FPR0
468	fld.d	$f9, \tmp, THREAD_FPR9  - THREAD_FPR0
469	fld.d	$f10, \tmp, THREAD_FPR10 - THREAD_FPR0
470	fld.d	$f11, \tmp, THREAD_FPR11 - THREAD_FPR0
471	fld.d	$f12, \tmp, THREAD_FPR12 - THREAD_FPR0
472	fld.d	$f13, \tmp, THREAD_FPR13 - THREAD_FPR0
473	fld.d	$f14, \tmp, THREAD_FPR14 - THREAD_FPR0
474	fld.d	$f15, \tmp, THREAD_FPR15 - THREAD_FPR0
475	fld.d	$f16, \tmp, THREAD_FPR16 - THREAD_FPR0
476	fld.d	$f17, \tmp, THREAD_FPR17 - THREAD_FPR0
477	fld.d	$f18, \tmp, THREAD_FPR18 - THREAD_FPR0
478	fld.d	$f19, \tmp, THREAD_FPR19 - THREAD_FPR0
479	fld.d	$f20, \tmp, THREAD_FPR20 - THREAD_FPR0
480	fld.d	$f21, \tmp, THREAD_FPR21 - THREAD_FPR0
481	fld.d	$f22, \tmp, THREAD_FPR22 - THREAD_FPR0
482	fld.d	$f23, \tmp, THREAD_FPR23 - THREAD_FPR0
483	fld.d	$f24, \tmp, THREAD_FPR24 - THREAD_FPR0
484	fld.d	$f25, \tmp, THREAD_FPR25 - THREAD_FPR0
485	fld.d	$f26, \tmp, THREAD_FPR26 - THREAD_FPR0
486	fld.d	$f27, \tmp, THREAD_FPR27 - THREAD_FPR0
487	fld.d	$f28, \tmp, THREAD_FPR28 - THREAD_FPR0
488	fld.d	$f29, \tmp, THREAD_FPR29 - THREAD_FPR0
489	fld.d	$f30, \tmp, THREAD_FPR30 - THREAD_FPR0
490	fld.d	$f31, \tmp, THREAD_FPR31 - THREAD_FPR0
491	.endm
492
493	.macro lsx_save_data thread tmp
494	parse_r __tmp, \tmp
495	li.w		\tmp, THREAD_FPR0
496	PTR_ADD 	\tmp, \thread, \tmp
497	/* vst opcode is 0xb1 */
498	.word (0xb1 << 22 | ((THREAD_FPR0-THREAD_FPR0) << 10) | __tmp << 5 | 0)
499	.word (0xb1 << 22 | ((THREAD_FPR1-THREAD_FPR0) << 10) | __tmp << 5 | 1)
500	.word (0xb1 << 22 | ((THREAD_FPR2-THREAD_FPR0) << 10) | __tmp << 5 | 2)
501	.word (0xb1 << 22 | ((THREAD_FPR3-THREAD_FPR0) << 10) | __tmp << 5 | 3)
502	.word (0xb1 << 22 | ((THREAD_FPR4-THREAD_FPR0) << 10) | __tmp << 5 | 4)
503	.word (0xb1 << 22 | ((THREAD_FPR5-THREAD_FPR0) << 10) | __tmp << 5 | 5)
504	.word (0xb1 << 22 | ((THREAD_FPR6-THREAD_FPR0) << 10) | __tmp << 5 | 6)
505	.word (0xb1 << 22 | ((THREAD_FPR7-THREAD_FPR0) << 10) | __tmp << 5 | 7)
506	.word (0xb1 << 22 | ((THREAD_FPR8-THREAD_FPR0) << 10) | __tmp << 5 | 8)
507	.word (0xb1 << 22 | ((THREAD_FPR9-THREAD_FPR0) << 10) | __tmp << 5 | 9)
508	.word (0xb1 << 22 | ((THREAD_FPR10-THREAD_FPR0) << 10) | __tmp << 5 | 10)
509	.word (0xb1 << 22 | ((THREAD_FPR11-THREAD_FPR0) << 10) | __tmp << 5 | 11)
510	.word (0xb1 << 22 | ((THREAD_FPR12-THREAD_FPR0) << 10) | __tmp << 5 | 12)
511	.word (0xb1 << 22 | ((THREAD_FPR13-THREAD_FPR0) << 10) | __tmp << 5 | 13)
512	.word (0xb1 << 22 | ((THREAD_FPR14-THREAD_FPR0) << 10) | __tmp << 5 | 14)
513	.word (0xb1 << 22 | ((THREAD_FPR15-THREAD_FPR0) << 10) | __tmp << 5 | 15)
514	.word (0xb1 << 22 | ((THREAD_FPR16-THREAD_FPR0) << 10) | __tmp << 5 | 16)
515	.word (0xb1 << 22 | ((THREAD_FPR17-THREAD_FPR0) << 10) | __tmp << 5 | 17)
516	.word (0xb1 << 22 | ((THREAD_FPR18-THREAD_FPR0) << 10) | __tmp << 5 | 18)
517	.word (0xb1 << 22 | ((THREAD_FPR19-THREAD_FPR0) << 10) | __tmp << 5 | 19)
518	.word (0xb1 << 22 | ((THREAD_FPR20-THREAD_FPR0) << 10) | __tmp << 5 | 20)
519	.word (0xb1 << 22 | ((THREAD_FPR21-THREAD_FPR0) << 10) | __tmp << 5 | 21)
520	.word (0xb1 << 22 | ((THREAD_FPR22-THREAD_FPR0) << 10) | __tmp << 5 | 22)
521	.word (0xb1 << 22 | ((THREAD_FPR23-THREAD_FPR0) << 10) | __tmp << 5 | 23)
522	.word (0xb1 << 22 | ((THREAD_FPR24-THREAD_FPR0) << 10) | __tmp << 5 | 24)
523	.word (0xb1 << 22 | ((THREAD_FPR25-THREAD_FPR0) << 10) | __tmp << 5 | 25)
524	.word (0xb1 << 22 | ((THREAD_FPR26-THREAD_FPR0) << 10) | __tmp << 5 | 26)
525	.word (0xb1 << 22 | ((THREAD_FPR27-THREAD_FPR0) << 10) | __tmp << 5 | 27)
526	.word (0xb1 << 22 | ((THREAD_FPR28-THREAD_FPR0) << 10) | __tmp << 5 | 28)
527	.word (0xb1 << 22 | ((THREAD_FPR29-THREAD_FPR0) << 10) | __tmp << 5 | 29)
528	.word (0xb1 << 22 | ((THREAD_FPR30-THREAD_FPR0) << 10) | __tmp << 5 | 30)
529	.word (0xb1 << 22 | ((THREAD_FPR31-THREAD_FPR0) << 10) | __tmp << 5 | 31)
530	.endm
531
532	.macro lsx_restore_data thread tmp
533	parse_r __tmp, \tmp
534	li.w		\tmp, THREAD_FPR0
535	PTR_ADD		\tmp, \thread, \tmp
536	/* vld opcode is 0xb0 */
537	.word (0xb0 << 22 | ((THREAD_FPR0-THREAD_FPR0) << 10) | __tmp << 5 | 0)
538	.word (0xb0 << 22 | ((THREAD_FPR1-THREAD_FPR0) << 10) | __tmp << 5 | 1)
539	.word (0xb0 << 22 | ((THREAD_FPR2-THREAD_FPR0) << 10) | __tmp << 5 | 2)
540	.word (0xb0 << 22 | ((THREAD_FPR3-THREAD_FPR0) << 10) | __tmp << 5 | 3)
541	.word (0xb0 << 22 | ((THREAD_FPR4-THREAD_FPR0) << 10) | __tmp << 5 | 4)
542	.word (0xb0 << 22 | ((THREAD_FPR5-THREAD_FPR0) << 10) | __tmp << 5 | 5)
543	.word (0xb0 << 22 | ((THREAD_FPR6-THREAD_FPR0) << 10) | __tmp << 5 | 6)
544	.word (0xb0 << 22 | ((THREAD_FPR7-THREAD_FPR0) << 10) | __tmp << 5 | 7)
545	.word (0xb0 << 22 | ((THREAD_FPR8-THREAD_FPR0) << 10) | __tmp << 5 | 8)
546	.word (0xb0 << 22 | ((THREAD_FPR9-THREAD_FPR0) << 10) | __tmp << 5 | 9)
547	.word (0xb0 << 22 | ((THREAD_FPR10-THREAD_FPR0) << 10) | __tmp << 5 | 10)
548	.word (0xb0 << 22 | ((THREAD_FPR11-THREAD_FPR0) << 10) | __tmp << 5 | 11)
549	.word (0xb0 << 22 | ((THREAD_FPR12-THREAD_FPR0) << 10) | __tmp << 5 | 12)
550	.word (0xb0 << 22 | ((THREAD_FPR13-THREAD_FPR0) << 10) | __tmp << 5 | 13)
551	.word (0xb0 << 22 | ((THREAD_FPR14-THREAD_FPR0) << 10) | __tmp << 5 | 14)
552	.word (0xb0 << 22 | ((THREAD_FPR15-THREAD_FPR0) << 10) | __tmp << 5 | 15)
553	.word (0xb0 << 22 | ((THREAD_FPR16-THREAD_FPR0) << 10) | __tmp << 5 | 16)
554	.word (0xb0 << 22 | ((THREAD_FPR17-THREAD_FPR0) << 10) | __tmp << 5 | 17)
555	.word (0xb0 << 22 | ((THREAD_FPR18-THREAD_FPR0) << 10) | __tmp << 5 | 18)
556	.word (0xb0 << 22 | ((THREAD_FPR19-THREAD_FPR0) << 10) | __tmp << 5 | 19)
557	.word (0xb0 << 22 | ((THREAD_FPR20-THREAD_FPR0) << 10) | __tmp << 5 | 20)
558	.word (0xb0 << 22 | ((THREAD_FPR21-THREAD_FPR0) << 10) | __tmp << 5 | 21)
559	.word (0xb0 << 22 | ((THREAD_FPR22-THREAD_FPR0) << 10) | __tmp << 5 | 22)
560	.word (0xb0 << 22 | ((THREAD_FPR23-THREAD_FPR0) << 10) | __tmp << 5 | 23)
561	.word (0xb0 << 22 | ((THREAD_FPR24-THREAD_FPR0) << 10) | __tmp << 5 | 24)
562	.word (0xb0 << 22 | ((THREAD_FPR25-THREAD_FPR0) << 10) | __tmp << 5 | 25)
563	.word (0xb0 << 22 | ((THREAD_FPR26-THREAD_FPR0) << 10) | __tmp << 5 | 26)
564	.word (0xb0 << 22 | ((THREAD_FPR27-THREAD_FPR0) << 10) | __tmp << 5 | 27)
565	.word (0xb0 << 22 | ((THREAD_FPR28-THREAD_FPR0) << 10) | __tmp << 5 | 28)
566	.word (0xb0 << 22 | ((THREAD_FPR29-THREAD_FPR0) << 10) | __tmp << 5 | 29)
567	.word (0xb0 << 22 | ((THREAD_FPR30-THREAD_FPR0) << 10) | __tmp << 5 | 30)
568	.word (0xb0 << 22 | ((THREAD_FPR31-THREAD_FPR0) << 10) | __tmp << 5 | 31)
569	.endm
570
571	.macro	lsx_save_all	thread tmp0 tmp1
572	fpu_save_cc	\thread, \tmp0, \tmp1
573	fpu_save_csr	\thread, \tmp0
574	lsx_save_data	\thread, \tmp0
575	.endm
576
577	.macro	lsx_restore_all	thread tmp0 tmp1
578	lsx_restore_data	\thread, \tmp0
579	fpu_restore_cc	\thread, \tmp0, \tmp1
580	fpu_restore_csr	\thread, \tmp0
581	.endm
582
583	.macro lsx_save_upper vd base tmp off
584	parse_vr __vd, \vd
585	parse_r __tmp, \tmp
586	/* vpickve2gr opcode is 0xe5dfe */
587	.word (0xe5dfe << 11 | 1 << 10 | __vd << 5 | __tmp)
588	st.d	\tmp, \base, (\off+8)
589	.endm
590
591	.macro lsx_save_all_upper thread base tmp
592	li.w	\tmp, THREAD_FPR0
593	PTR_ADD	\base, \thread, \tmp
594	lsx_save_upper $vr0,  \base, \tmp, (THREAD_FPR0-THREAD_FPR0)
595	lsx_save_upper $vr1,  \base, \tmp, (THREAD_FPR1-THREAD_FPR0)
596	lsx_save_upper $vr2,  \base, \tmp, (THREAD_FPR2-THREAD_FPR0)
597	lsx_save_upper $vr3,  \base, \tmp, (THREAD_FPR3-THREAD_FPR0)
598	lsx_save_upper $vr4,  \base, \tmp, (THREAD_FPR4-THREAD_FPR0)
599	lsx_save_upper $vr5,  \base, \tmp, (THREAD_FPR5-THREAD_FPR0)
600	lsx_save_upper $vr6,  \base, \tmp, (THREAD_FPR6-THREAD_FPR0)
601	lsx_save_upper $vr7,  \base, \tmp, (THREAD_FPR7-THREAD_FPR0)
602	lsx_save_upper $vr8,  \base, \tmp, (THREAD_FPR8-THREAD_FPR0)
603	lsx_save_upper $vr9,  \base, \tmp, (THREAD_FPR9-THREAD_FPR0)
604	lsx_save_upper $vr10, \base, \tmp, (THREAD_FPR10-THREAD_FPR0)
605	lsx_save_upper $vr11, \base, \tmp, (THREAD_FPR11-THREAD_FPR0)
606	lsx_save_upper $vr12, \base, \tmp, (THREAD_FPR12-THREAD_FPR0)
607	lsx_save_upper $vr13, \base, \tmp, (THREAD_FPR13-THREAD_FPR0)
608	lsx_save_upper $vr14, \base, \tmp, (THREAD_FPR14-THREAD_FPR0)
609	lsx_save_upper $vr15, \base, \tmp, (THREAD_FPR15-THREAD_FPR0)
610	lsx_save_upper $vr16, \base, \tmp, (THREAD_FPR16-THREAD_FPR0)
611	lsx_save_upper $vr17, \base, \tmp, (THREAD_FPR17-THREAD_FPR0)
612	lsx_save_upper $vr18, \base, \tmp, (THREAD_FPR18-THREAD_FPR0)
613	lsx_save_upper $vr19, \base, \tmp, (THREAD_FPR19-THREAD_FPR0)
614	lsx_save_upper $vr20, \base, \tmp, (THREAD_FPR20-THREAD_FPR0)
615	lsx_save_upper $vr21, \base, \tmp, (THREAD_FPR21-THREAD_FPR0)
616	lsx_save_upper $vr22, \base, \tmp, (THREAD_FPR22-THREAD_FPR0)
617	lsx_save_upper $vr23, \base, \tmp, (THREAD_FPR23-THREAD_FPR0)
618	lsx_save_upper $vr24, \base, \tmp, (THREAD_FPR24-THREAD_FPR0)
619	lsx_save_upper $vr25, \base, \tmp, (THREAD_FPR25-THREAD_FPR0)
620	lsx_save_upper $vr26, \base, \tmp, (THREAD_FPR26-THREAD_FPR0)
621	lsx_save_upper $vr27, \base, \tmp, (THREAD_FPR27-THREAD_FPR0)
622	lsx_save_upper $vr28, \base, \tmp, (THREAD_FPR28-THREAD_FPR0)
623	lsx_save_upper $vr29, \base, \tmp, (THREAD_FPR29-THREAD_FPR0)
624	lsx_save_upper $vr30, \base, \tmp, (THREAD_FPR30-THREAD_FPR0)
625	lsx_save_upper $vr31, \base, \tmp, (THREAD_FPR31-THREAD_FPR0)
626	.endm
627
628	.macro lsx_restore_upper vd base tmp off
629	parse_vr __vd, \vd
630	parse_r __tmp, \tmp
631	ld.d	\tmp, \base, (\off+8)
632	/* vinsgr2vr opcode is 0xe5d7e */
633	.word	(0xe5d7e << 11 | 1 << 10 | __tmp << 5 | __vd)
634	.endm
635
636	.macro lsx_restore_all_upper thread base tmp
637	li.w	\tmp, THREAD_FPR0
638	PTR_ADD	\base, \thread, \tmp
639	lsx_restore_upper $vr0,  \base, \tmp, (THREAD_FPR0-THREAD_FPR0)
640	lsx_restore_upper $vr1,  \base, \tmp, (THREAD_FPR1-THREAD_FPR0)
641	lsx_restore_upper $vr2,  \base, \tmp, (THREAD_FPR2-THREAD_FPR0)
642	lsx_restore_upper $vr3,  \base, \tmp, (THREAD_FPR3-THREAD_FPR0)
643	lsx_restore_upper $vr4,  \base, \tmp, (THREAD_FPR4-THREAD_FPR0)
644	lsx_restore_upper $vr5,  \base, \tmp, (THREAD_FPR5-THREAD_FPR0)
645	lsx_restore_upper $vr6,  \base, \tmp, (THREAD_FPR6-THREAD_FPR0)
646	lsx_restore_upper $vr7,  \base, \tmp, (THREAD_FPR7-THREAD_FPR0)
647	lsx_restore_upper $vr8,  \base, \tmp, (THREAD_FPR8-THREAD_FPR0)
648	lsx_restore_upper $vr9,  \base, \tmp, (THREAD_FPR9-THREAD_FPR0)
649	lsx_restore_upper $vr10, \base, \tmp, (THREAD_FPR10-THREAD_FPR0)
650	lsx_restore_upper $vr11, \base, \tmp, (THREAD_FPR11-THREAD_FPR0)
651	lsx_restore_upper $vr12, \base, \tmp, (THREAD_FPR12-THREAD_FPR0)
652	lsx_restore_upper $vr13, \base, \tmp, (THREAD_FPR13-THREAD_FPR0)
653	lsx_restore_upper $vr14, \base, \tmp, (THREAD_FPR14-THREAD_FPR0)
654	lsx_restore_upper $vr15, \base, \tmp, (THREAD_FPR15-THREAD_FPR0)
655	lsx_restore_upper $vr16, \base, \tmp, (THREAD_FPR16-THREAD_FPR0)
656	lsx_restore_upper $vr17, \base, \tmp, (THREAD_FPR17-THREAD_FPR0)
657	lsx_restore_upper $vr18, \base, \tmp, (THREAD_FPR18-THREAD_FPR0)
658	lsx_restore_upper $vr19, \base, \tmp, (THREAD_FPR19-THREAD_FPR0)
659	lsx_restore_upper $vr20, \base, \tmp, (THREAD_FPR20-THREAD_FPR0)
660	lsx_restore_upper $vr21, \base, \tmp, (THREAD_FPR21-THREAD_FPR0)
661	lsx_restore_upper $vr22, \base, \tmp, (THREAD_FPR22-THREAD_FPR0)
662	lsx_restore_upper $vr23, \base, \tmp, (THREAD_FPR23-THREAD_FPR0)
663	lsx_restore_upper $vr24, \base, \tmp, (THREAD_FPR24-THREAD_FPR0)
664	lsx_restore_upper $vr25, \base, \tmp, (THREAD_FPR25-THREAD_FPR0)
665	lsx_restore_upper $vr26, \base, \tmp, (THREAD_FPR26-THREAD_FPR0)
666	lsx_restore_upper $vr27, \base, \tmp, (THREAD_FPR27-THREAD_FPR0)
667	lsx_restore_upper $vr28, \base, \tmp, (THREAD_FPR28-THREAD_FPR0)
668	lsx_restore_upper $vr29, \base, \tmp, (THREAD_FPR29-THREAD_FPR0)
669	lsx_restore_upper $vr30, \base, \tmp, (THREAD_FPR30-THREAD_FPR0)
670	lsx_restore_upper $vr31, \base, \tmp, (THREAD_FPR31-THREAD_FPR0)
671	.endm
672
673	.macro	lsx_init_upper vd tmp
674	parse_vr __vd, \vd
675	parse_r __tmp, \tmp
676	/* vinsgr2vr opcode is 0xe5d7e */
677	.word	(0xe5d7e << 11 | 1 << 10 | __tmp << 5 | __vd)
678	.endm
679
680	.macro	lsx_init_all_upper tmp
681	not	\tmp, zero
682	lsx_init_upper	$vr0 \tmp
683	lsx_init_upper	$vr1 \tmp
684	lsx_init_upper	$vr2 \tmp
685	lsx_init_upper	$vr3 \tmp
686	lsx_init_upper	$vr4 \tmp
687	lsx_init_upper	$vr5 \tmp
688	lsx_init_upper	$vr6 \tmp
689	lsx_init_upper	$vr7 \tmp
690	lsx_init_upper	$vr8 \tmp
691	lsx_init_upper	$vr9 \tmp
692	lsx_init_upper	$vr10 \tmp
693	lsx_init_upper	$vr11 \tmp
694	lsx_init_upper	$vr12 \tmp
695	lsx_init_upper	$vr13 \tmp
696	lsx_init_upper	$vr14 \tmp
697	lsx_init_upper	$vr15 \tmp
698	lsx_init_upper	$vr16 \tmp
699	lsx_init_upper	$vr17 \tmp
700	lsx_init_upper	$vr18 \tmp
701	lsx_init_upper	$vr19 \tmp
702	lsx_init_upper	$vr20 \tmp
703	lsx_init_upper	$vr21 \tmp
704	lsx_init_upper	$vr22 \tmp
705	lsx_init_upper	$vr23 \tmp
706	lsx_init_upper	$vr24 \tmp
707	lsx_init_upper	$vr25 \tmp
708	lsx_init_upper	$vr26 \tmp
709	lsx_init_upper	$vr27 \tmp
710	lsx_init_upper	$vr28 \tmp
711	lsx_init_upper	$vr29 \tmp
712	lsx_init_upper	$vr30 \tmp
713	lsx_init_upper	$vr31 \tmp
714	.endm
715
716	.macro lasx_save_data thread tmp
717	parse_r __tmp, \tmp
718	li.w            \tmp, THREAD_FPR0
719	PTR_ADD         \tmp, \thread, \tmp
720	/* xvst opcode is 0xb3 */
721	.word (0xb3 << 22 | ((THREAD_FPR0-THREAD_FPR0) << 10) | __tmp << 5 | 0)
722	.word (0xb3 << 22 | ((THREAD_FPR1-THREAD_FPR0) << 10) | __tmp << 5 | 1)
723	.word (0xb3 << 22 | ((THREAD_FPR2-THREAD_FPR0) << 10) | __tmp << 5 | 2)
724	.word (0xb3 << 22 | ((THREAD_FPR3-THREAD_FPR0) << 10) | __tmp << 5 | 3)
725	.word (0xb3 << 22 | ((THREAD_FPR4-THREAD_FPR0) << 10) | __tmp << 5 | 4)
726	.word (0xb3 << 22 | ((THREAD_FPR5-THREAD_FPR0) << 10) | __tmp << 5 | 5)
727	.word (0xb3 << 22 | ((THREAD_FPR6-THREAD_FPR0) << 10) | __tmp << 5 | 6)
728	.word (0xb3 << 22 | ((THREAD_FPR7-THREAD_FPR0) << 10) | __tmp << 5 | 7)
729	.word (0xb3 << 22 | ((THREAD_FPR8-THREAD_FPR0) << 10) | __tmp << 5 | 8)
730	.word (0xb3 << 22 | ((THREAD_FPR9-THREAD_FPR0) << 10) | __tmp << 5 | 9)
731	.word (0xb3 << 22 | ((THREAD_FPR10-THREAD_FPR0) << 10) | __tmp << 5 | 10)
732	.word (0xb3 << 22 | ((THREAD_FPR11-THREAD_FPR0) << 10) | __tmp << 5 | 11)
733	.word (0xb3 << 22 | ((THREAD_FPR12-THREAD_FPR0) << 10) | __tmp << 5 | 12)
734	.word (0xb3 << 22 | ((THREAD_FPR13-THREAD_FPR0) << 10) | __tmp << 5 | 13)
735	.word (0xb3 << 22 | ((THREAD_FPR14-THREAD_FPR0) << 10) | __tmp << 5 | 14)
736	.word (0xb3 << 22 | ((THREAD_FPR15-THREAD_FPR0) << 10) | __tmp << 5 | 15)
737	.word (0xb3 << 22 | ((THREAD_FPR16-THREAD_FPR0) << 10) | __tmp << 5 | 16)
738	.word (0xb3 << 22 | ((THREAD_FPR17-THREAD_FPR0) << 10) | __tmp << 5 | 17)
739	.word (0xb3 << 22 | ((THREAD_FPR18-THREAD_FPR0) << 10) | __tmp << 5 | 18)
740	.word (0xb3 << 22 | ((THREAD_FPR19-THREAD_FPR0) << 10) | __tmp << 5 | 19)
741	.word (0xb3 << 22 | ((THREAD_FPR20-THREAD_FPR0) << 10) | __tmp << 5 | 20)
742	.word (0xb3 << 22 | ((THREAD_FPR21-THREAD_FPR0) << 10) | __tmp << 5 | 21)
743	.word (0xb3 << 22 | ((THREAD_FPR22-THREAD_FPR0) << 10) | __tmp << 5 | 22)
744	.word (0xb3 << 22 | ((THREAD_FPR23-THREAD_FPR0) << 10) | __tmp << 5 | 23)
745	.word (0xb3 << 22 | ((THREAD_FPR24-THREAD_FPR0) << 10) | __tmp << 5 | 24)
746	.word (0xb3 << 22 | ((THREAD_FPR25-THREAD_FPR0) << 10) | __tmp << 5 | 25)
747	.word (0xb3 << 22 | ((THREAD_FPR26-THREAD_FPR0) << 10) | __tmp << 5 | 26)
748	.word (0xb3 << 22 | ((THREAD_FPR27-THREAD_FPR0) << 10) | __tmp << 5 | 27)
749	.word (0xb3 << 22 | ((THREAD_FPR28-THREAD_FPR0) << 10) | __tmp << 5 | 28)
750	.word (0xb3 << 22 | ((THREAD_FPR29-THREAD_FPR0) << 10) | __tmp << 5 | 29)
751	.word (0xb3 << 22 | ((THREAD_FPR30-THREAD_FPR0) << 10) | __tmp << 5 | 30)
752	.word (0xb3 << 22 | ((THREAD_FPR31-THREAD_FPR0) << 10) | __tmp << 5 | 31)
753	.endm
754
755	.macro lasx_restore_data thread tmp
756	parse_r __tmp, \tmp
757	li.w            \tmp, THREAD_FPR0
758	PTR_ADD         \tmp, \thread, \tmp
759	/* xvld opcode is 0xb2 */
760	.word (0xb2 << 22 | ((THREAD_FPR0-THREAD_FPR0) << 10) | __tmp << 5 | 0)
761	.word (0xb2 << 22 | ((THREAD_FPR1-THREAD_FPR0) << 10) | __tmp << 5 | 1)
762	.word (0xb2 << 22 | ((THREAD_FPR2-THREAD_FPR0) << 10) | __tmp << 5 | 2)
763	.word (0xb2 << 22 | ((THREAD_FPR3-THREAD_FPR0) << 10) | __tmp << 5 | 3)
764	.word (0xb2 << 22 | ((THREAD_FPR4-THREAD_FPR0) << 10) | __tmp << 5 | 4)
765	.word (0xb2 << 22 | ((THREAD_FPR5-THREAD_FPR0) << 10) | __tmp << 5 | 5)
766	.word (0xb2 << 22 | ((THREAD_FPR6-THREAD_FPR0) << 10) | __tmp << 5 | 6)
767	.word (0xb2 << 22 | ((THREAD_FPR7-THREAD_FPR0) << 10) | __tmp << 5 | 7)
768	.word (0xb2 << 22 | ((THREAD_FPR8-THREAD_FPR0) << 10) | __tmp << 5 | 8)
769	.word (0xb2 << 22 | ((THREAD_FPR9-THREAD_FPR0) << 10) | __tmp << 5 | 9)
770	.word (0xb2 << 22 | ((THREAD_FPR10-THREAD_FPR0) << 10) | __tmp << 5 | 10)
771	.word (0xb2 << 22 | ((THREAD_FPR11-THREAD_FPR0) << 10) | __tmp << 5 | 11)
772	.word (0xb2 << 22 | ((THREAD_FPR12-THREAD_FPR0) << 10) | __tmp << 5 | 12)
773	.word (0xb2 << 22 | ((THREAD_FPR13-THREAD_FPR0) << 10) | __tmp << 5 | 13)
774	.word (0xb2 << 22 | ((THREAD_FPR14-THREAD_FPR0) << 10) | __tmp << 5 | 14)
775	.word (0xb2 << 22 | ((THREAD_FPR15-THREAD_FPR0) << 10) | __tmp << 5 | 15)
776	.word (0xb2 << 22 | ((THREAD_FPR16-THREAD_FPR0) << 10) | __tmp << 5 | 16)
777	.word (0xb2 << 22 | ((THREAD_FPR17-THREAD_FPR0) << 10) | __tmp << 5 | 17)
778	.word (0xb2 << 22 | ((THREAD_FPR18-THREAD_FPR0) << 10) | __tmp << 5 | 18)
779	.word (0xb2 << 22 | ((THREAD_FPR19-THREAD_FPR0) << 10) | __tmp << 5 | 19)
780	.word (0xb2 << 22 | ((THREAD_FPR20-THREAD_FPR0) << 10) | __tmp << 5 | 20)
781	.word (0xb2 << 22 | ((THREAD_FPR21-THREAD_FPR0) << 10) | __tmp << 5 | 21)
782	.word (0xb2 << 22 | ((THREAD_FPR22-THREAD_FPR0) << 10) | __tmp << 5 | 22)
783	.word (0xb2 << 22 | ((THREAD_FPR23-THREAD_FPR0) << 10) | __tmp << 5 | 23)
784	.word (0xb2 << 22 | ((THREAD_FPR24-THREAD_FPR0) << 10) | __tmp << 5 | 24)
785	.word (0xb2 << 22 | ((THREAD_FPR25-THREAD_FPR0) << 10) | __tmp << 5 | 25)
786	.word (0xb2 << 22 | ((THREAD_FPR26-THREAD_FPR0) << 10) | __tmp << 5 | 26)
787	.word (0xb2 << 22 | ((THREAD_FPR27-THREAD_FPR0) << 10) | __tmp << 5 | 27)
788	.word (0xb2 << 22 | ((THREAD_FPR28-THREAD_FPR0) << 10) | __tmp << 5 | 28)
789	.word (0xb2 << 22 | ((THREAD_FPR29-THREAD_FPR0) << 10) | __tmp << 5 | 29)
790	.word (0xb2 << 22 | ((THREAD_FPR30-THREAD_FPR0) << 10) | __tmp << 5 | 30)
791	.word (0xb2 << 22 | ((THREAD_FPR31-THREAD_FPR0) << 10) | __tmp << 5 | 31)
792	.endm
793
794	.macro	lasx_save_all	thread tmp0 tmp1
795	fpu_save_cc	\thread, \tmp0, \tmp1
796	fpu_save_csr	\thread, \tmp0
797	lasx_save_data	\thread, \tmp0
798	.endm
799
800	.macro	lasx_restore_all thread tmp0 tmp1
801	lasx_restore_data	\thread, \tmp0
802	fpu_restore_cc	\thread, \tmp0, \tmp1
803	fpu_restore_csr	\thread, \tmp0
804	.endm
805
806	.macro lasx_save_upper xd base tmp off
807	/* Nothing */
808	.endm
809
810	.macro lasx_save_all_upper thread base tmp
811	/* Nothing */
812	.endm
813
814	.macro lasx_restore_upper xd base tmp off
815	parse_xr __xd, \xd
816	parse_xr __xt, \tmp
817	parse_r __base, \base
818	/* vld opcode is 0xb0 */
819	.word (0xb0 << 22 | (\off+16) << 10 | __base << 5 | __xt)
820	/* xvpermi.q opcode is 0x1dfb */
821	.word (0x1dfb << 18 | 0x2 << 10 | __xt << 5 | __xd)
822	.endm
823
824	.macro lasx_restore_all_upper thread base tmp
825	li.w	\tmp, THREAD_FPR0
826	PTR_ADD	\base, \thread, \tmp
827	/* Save $vr31, xvpickve2gr opcode is 0x76efe */
828	.word (0x76efe << 12 | 0 << 10 | 31 << 5 | 0x11)
829	.word (0x76efe << 12 | 1 << 10 | 31 << 5 | 0x12)
830	lasx_restore_upper $xr0, \base, $xr31, (THREAD_FPR0-THREAD_FPR0)
831	lasx_restore_upper $xr1, \base, $xr31, (THREAD_FPR1-THREAD_FPR0)
832	lasx_restore_upper $xr2, \base, $xr31, (THREAD_FPR2-THREAD_FPR0)
833	lasx_restore_upper $xr3, \base, $xr31, (THREAD_FPR3-THREAD_FPR0)
834	lasx_restore_upper $xr4, \base, $xr31, (THREAD_FPR4-THREAD_FPR0)
835	lasx_restore_upper $xr5, \base, $xr31, (THREAD_FPR5-THREAD_FPR0)
836	lasx_restore_upper $xr6, \base, $xr31, (THREAD_FPR6-THREAD_FPR0)
837	lasx_restore_upper $xr7, \base, $xr31, (THREAD_FPR7-THREAD_FPR0)
838	lasx_restore_upper $xr8, \base, $xr31, (THREAD_FPR8-THREAD_FPR0)
839	lasx_restore_upper $xr9, \base, $xr31, (THREAD_FPR9-THREAD_FPR0)
840	lasx_restore_upper $xr10, \base, $xr31, (THREAD_FPR10-THREAD_FPR0)
841	lasx_restore_upper $xr11, \base, $xr31, (THREAD_FPR11-THREAD_FPR0)
842	lasx_restore_upper $xr12, \base, $xr31, (THREAD_FPR12-THREAD_FPR0)
843	lasx_restore_upper $xr13, \base, $xr31, (THREAD_FPR13-THREAD_FPR0)
844	lasx_restore_upper $xr14, \base, $xr31, (THREAD_FPR14-THREAD_FPR0)
845	lasx_restore_upper $xr15, \base, $xr31, (THREAD_FPR15-THREAD_FPR0)
846	lasx_restore_upper $xr16, \base, $xr31, (THREAD_FPR16-THREAD_FPR0)
847	lasx_restore_upper $xr17, \base, $xr31, (THREAD_FPR17-THREAD_FPR0)
848	lasx_restore_upper $xr18, \base, $xr31, (THREAD_FPR18-THREAD_FPR0)
849	lasx_restore_upper $xr19, \base, $xr31, (THREAD_FPR19-THREAD_FPR0)
850	lasx_restore_upper $xr20, \base, $xr31, (THREAD_FPR20-THREAD_FPR0)
851	lasx_restore_upper $xr21, \base, $xr31, (THREAD_FPR21-THREAD_FPR0)
852	lasx_restore_upper $xr22, \base, $xr31, (THREAD_FPR22-THREAD_FPR0)
853	lasx_restore_upper $xr23, \base, $xr31, (THREAD_FPR23-THREAD_FPR0)
854	lasx_restore_upper $xr24, \base, $xr31, (THREAD_FPR24-THREAD_FPR0)
855	lasx_restore_upper $xr25, \base, $xr31, (THREAD_FPR25-THREAD_FPR0)
856	lasx_restore_upper $xr26, \base, $xr31, (THREAD_FPR26-THREAD_FPR0)
857	lasx_restore_upper $xr27, \base, $xr31, (THREAD_FPR27-THREAD_FPR0)
858	lasx_restore_upper $xr28, \base, $xr31, (THREAD_FPR28-THREAD_FPR0)
859	lasx_restore_upper $xr29, \base, $xr31, (THREAD_FPR29-THREAD_FPR0)
860	lasx_restore_upper $xr30, \base, $xr31, (THREAD_FPR30-THREAD_FPR0)
861	lasx_restore_upper $xr31, \base, $xr31, (THREAD_FPR31-THREAD_FPR0)
862	/* Restore $vr31, xvinsgr2vr opcode is 0x76ebe */
863	.word (0x76ebe << 12 | 0 << 10 | 0x11 << 5 | 31)
864	.word (0x76ebe << 12 | 1 << 10 | 0x12 << 5 | 31)
865	.endm
866
867	.macro	lasx_init_upper xd tmp
868	parse_xr __xd, \xd
869	parse_r __tmp, \tmp
870	/* xvinsgr2vr opcode is 0x76ebe */
871	.word	(0x76ebe << 12 | 2 << 10 | __tmp << 5 | __xd)
872	.word	(0x76ebe << 12 | 3 << 10 | __tmp << 5 | __xd)
873	.endm
874
875	.macro	lasx_init_all_upper tmp
876	not	\tmp, zero
877	lasx_init_upper	$xr0 \tmp
878	lasx_init_upper	$xr1 \tmp
879	lasx_init_upper	$xr2 \tmp
880	lasx_init_upper	$xr3 \tmp
881	lasx_init_upper	$xr4 \tmp
882	lasx_init_upper	$xr5 \tmp
883	lasx_init_upper	$xr6 \tmp
884	lasx_init_upper	$xr7 \tmp
885	lasx_init_upper	$xr8 \tmp
886	lasx_init_upper	$xr9 \tmp
887	lasx_init_upper	$xr10 \tmp
888	lasx_init_upper	$xr11 \tmp
889	lasx_init_upper	$xr12 \tmp
890	lasx_init_upper	$xr13 \tmp
891	lasx_init_upper	$xr14 \tmp
892	lasx_init_upper	$xr15 \tmp
893	lasx_init_upper	$xr16 \tmp
894	lasx_init_upper	$xr17 \tmp
895	lasx_init_upper	$xr18 \tmp
896	lasx_init_upper	$xr19 \tmp
897	lasx_init_upper	$xr20 \tmp
898	lasx_init_upper	$xr21 \tmp
899	lasx_init_upper	$xr22 \tmp
900	lasx_init_upper	$xr23 \tmp
901	lasx_init_upper	$xr24 \tmp
902	lasx_init_upper	$xr25 \tmp
903	lasx_init_upper	$xr26 \tmp
904	lasx_init_upper	$xr27 \tmp
905	lasx_init_upper	$xr28 \tmp
906	lasx_init_upper	$xr29 \tmp
907	lasx_init_upper	$xr30 \tmp
908	lasx_init_upper	$xr31 \tmp
909	.endm
910
911.macro jr dst
912	jirl	zero, \dst, 0
913.endm
914
915.macro jalr	dst
916	jirl	ra, \dst, 0
917.endm
918
919.macro not dst src
920	nor	\dst, \src, zero
921.endm
922
923.macro bgt r0 r1 label
924	blt	\r1, \r0, \label
925.endm
926
927.macro bltz r0 label
928	blt	\r0, zero, \label
929.endm
930
931.macro bgez r0 label
932	bge	\r0, zero, \label
933.endm
934
935#endif /* _ASM_ASMMACRO_H */
936