1/* SPDX-License-Identifier: GPL-2.0 */
2	/* This is trivial with the new code... */
3	.globl		do_fpdis
4	.type		do_fpdis,#function
5do_fpdis:
6	sethi		%hi(TSTATE_PEF), %g4
7	rdpr		%tstate, %g5
8	andcc		%g5, %g4, %g0
9	be,pt		%xcc, 1f
10	 nop
11	rd		%fprs, %g5
12	andcc		%g5, FPRS_FEF, %g0
13	be,pt		%xcc, 1f
14	 nop
15
16	/* Legal state when DCR_IFPOE is set in Cheetah %dcr. */
17	sethi		%hi(109f), %g7
18	ba,pt		%xcc, etrap
19109:	 or		%g7, %lo(109b), %g7
20	add		%g0, %g0, %g0
21	ba,a,pt		%xcc, rtrap
22
231:	TRAP_LOAD_THREAD_REG(%g6, %g1)
24	ldub		[%g6 + TI_FPSAVED], %g5
25	wr		%g0, FPRS_FEF, %fprs
26	andcc		%g5, FPRS_FEF, %g0
27	be,a,pt		%icc, 1f
28	 clr		%g7
29	ldx		[%g6 + TI_GSR], %g7
301:	andcc		%g5, FPRS_DL, %g0
31	bne,pn		%icc, 2f
32	 fzero		%f0
33	andcc		%g5, FPRS_DU, %g0
34	bne,pn		%icc, 1f
35	 fzero		%f2
36	faddd		%f0, %f2, %f4
37	fmuld		%f0, %f2, %f6
38	faddd		%f0, %f2, %f8
39	fmuld		%f0, %f2, %f10
40	faddd		%f0, %f2, %f12
41	fmuld		%f0, %f2, %f14
42	faddd		%f0, %f2, %f16
43	fmuld		%f0, %f2, %f18
44	faddd		%f0, %f2, %f20
45	fmuld		%f0, %f2, %f22
46	faddd		%f0, %f2, %f24
47	fmuld		%f0, %f2, %f26
48	faddd		%f0, %f2, %f28
49	fmuld		%f0, %f2, %f30
50	faddd		%f0, %f2, %f32
51	fmuld		%f0, %f2, %f34
52	faddd		%f0, %f2, %f36
53	fmuld		%f0, %f2, %f38
54	faddd		%f0, %f2, %f40
55	fmuld		%f0, %f2, %f42
56	faddd		%f0, %f2, %f44
57	fmuld		%f0, %f2, %f46
58	faddd		%f0, %f2, %f48
59	fmuld		%f0, %f2, %f50
60	faddd		%f0, %f2, %f52
61	fmuld		%f0, %f2, %f54
62	faddd		%f0, %f2, %f56
63	fmuld		%f0, %f2, %f58
64	b,pt		%xcc, fpdis_exit2
65	 faddd		%f0, %f2, %f60
661:	mov		SECONDARY_CONTEXT, %g3
67	add		%g6, TI_FPREGS + 0x80, %g1
68	faddd		%f0, %f2, %f4
69	fmuld		%f0, %f2, %f6
70
71661:	ldxa		[%g3] ASI_DMMU, %g5
72	.section	.sun4v_1insn_patch, "ax"
73	.word		661b
74	ldxa		[%g3] ASI_MMU, %g5
75	.previous
76
77	sethi		%hi(sparc64_kern_sec_context), %g2
78	ldx		[%g2 + %lo(sparc64_kern_sec_context)], %g2
79
80661:	stxa		%g2, [%g3] ASI_DMMU
81	.section	.sun4v_1insn_patch, "ax"
82	.word		661b
83	stxa		%g2, [%g3] ASI_MMU
84	.previous
85
86	membar		#Sync
87	add		%g6, TI_FPREGS + 0xc0, %g2
88	faddd		%f0, %f2, %f8
89	fmuld		%f0, %f2, %f10
90	membar		#Sync
91	ldda		[%g1] ASI_BLK_S, %f32
92	ldda		[%g2] ASI_BLK_S, %f48
93	membar		#Sync
94	faddd		%f0, %f2, %f12
95	fmuld		%f0, %f2, %f14
96	faddd		%f0, %f2, %f16
97	fmuld		%f0, %f2, %f18
98	faddd		%f0, %f2, %f20
99	fmuld		%f0, %f2, %f22
100	faddd		%f0, %f2, %f24
101	fmuld		%f0, %f2, %f26
102	faddd		%f0, %f2, %f28
103	fmuld		%f0, %f2, %f30
104	ba,a,pt		%xcc, fpdis_exit
105
1062:	andcc		%g5, FPRS_DU, %g0
107	bne,pt		%icc, 3f
108	 fzero		%f32
109	mov		SECONDARY_CONTEXT, %g3
110	fzero		%f34
111
112661:	ldxa		[%g3] ASI_DMMU, %g5
113	.section	.sun4v_1insn_patch, "ax"
114	.word		661b
115	ldxa		[%g3] ASI_MMU, %g5
116	.previous
117
118	add		%g6, TI_FPREGS, %g1
119	sethi		%hi(sparc64_kern_sec_context), %g2
120	ldx		[%g2 + %lo(sparc64_kern_sec_context)], %g2
121
122661:	stxa		%g2, [%g3] ASI_DMMU
123	.section	.sun4v_1insn_patch, "ax"
124	.word		661b
125	stxa		%g2, [%g3] ASI_MMU
126	.previous
127
128	membar		#Sync
129	add		%g6, TI_FPREGS + 0x40, %g2
130	faddd		%f32, %f34, %f36
131	fmuld		%f32, %f34, %f38
132	membar		#Sync
133	ldda		[%g1] ASI_BLK_S, %f0
134	ldda		[%g2] ASI_BLK_S, %f16
135	membar		#Sync
136	faddd		%f32, %f34, %f40
137	fmuld		%f32, %f34, %f42
138	faddd		%f32, %f34, %f44
139	fmuld		%f32, %f34, %f46
140	faddd		%f32, %f34, %f48
141	fmuld		%f32, %f34, %f50
142	faddd		%f32, %f34, %f52
143	fmuld		%f32, %f34, %f54
144	faddd		%f32, %f34, %f56
145	fmuld		%f32, %f34, %f58
146	faddd		%f32, %f34, %f60
147	fmuld		%f32, %f34, %f62
148	ba,a,pt		%xcc, fpdis_exit
149
1503:	mov		SECONDARY_CONTEXT, %g3
151	add		%g6, TI_FPREGS, %g1
152
153661:	ldxa		[%g3] ASI_DMMU, %g5
154	.section	.sun4v_1insn_patch, "ax"
155	.word		661b
156	ldxa		[%g3] ASI_MMU, %g5
157	.previous
158
159	sethi		%hi(sparc64_kern_sec_context), %g2
160	ldx		[%g2 + %lo(sparc64_kern_sec_context)], %g2
161
162661:	stxa		%g2, [%g3] ASI_DMMU
163	.section	.sun4v_1insn_patch, "ax"
164	.word		661b
165	stxa		%g2, [%g3] ASI_MMU
166	.previous
167
168	membar		#Sync
169	mov		0x40, %g2
170	membar		#Sync
171	ldda		[%g1] ASI_BLK_S, %f0
172	ldda		[%g1 + %g2] ASI_BLK_S, %f16
173	add		%g1, 0x80, %g1
174	ldda		[%g1] ASI_BLK_S, %f32
175	ldda		[%g1 + %g2] ASI_BLK_S, %f48
176	membar		#Sync
177fpdis_exit:
178
179661:	stxa		%g5, [%g3] ASI_DMMU
180	.section	.sun4v_1insn_patch, "ax"
181	.word		661b
182	stxa		%g5, [%g3] ASI_MMU
183	.previous
184
185	membar		#Sync
186fpdis_exit2:
187	wr		%g7, 0, %gsr
188	ldx		[%g6 + TI_XFSR], %fsr
189	rdpr		%tstate, %g3
190	or		%g3, %g4, %g3		! anal...
191	wrpr		%g3, %tstate
192	wr		%g0, FPRS_FEF, %fprs	! clean DU/DL bits
193	retry
194	.size		do_fpdis,.-do_fpdis
195
196	.align		32
197	.type		fp_other_bounce,#function
198fp_other_bounce:
199	call		do_fpother
200	 add		%sp, PTREGS_OFF, %o0
201	ba,a,pt		%xcc, rtrap
202	.size		fp_other_bounce,.-fp_other_bounce
203
204	.align		32
205	.globl		do_fpother_check_fitos
206	.type		do_fpother_check_fitos,#function
207do_fpother_check_fitos:
208	TRAP_LOAD_THREAD_REG(%g6, %g1)
209	sethi		%hi(fp_other_bounce - 4), %g7
210	or		%g7, %lo(fp_other_bounce - 4), %g7
211
212	/* NOTE: Need to preserve %g7 until we fully commit
213	 *       to the fitos fixup.
214	 */
215	stx		%fsr, [%g6 + TI_XFSR]
216	rdpr		%tstate, %g3
217	andcc		%g3, TSTATE_PRIV, %g0
218	bne,pn		%xcc, do_fptrap_after_fsr
219	 nop
220	ldx		[%g6 + TI_XFSR], %g3
221	srlx		%g3, 14, %g1
222	and		%g1, 7, %g1
223	cmp		%g1, 2			! Unfinished FP-OP
224	bne,pn		%xcc, do_fptrap_after_fsr
225	 sethi		%hi(1 << 23), %g1	! Inexact
226	andcc		%g3, %g1, %g0
227	bne,pn		%xcc, do_fptrap_after_fsr
228	 rdpr		%tpc, %g1
229	lduwa		[%g1] ASI_AIUP, %g3	! This cannot ever fail
230#define FITOS_MASK	0xc1f83fe0
231#define FITOS_COMPARE	0x81a01880
232	sethi		%hi(FITOS_MASK), %g1
233	or		%g1, %lo(FITOS_MASK), %g1
234	and		%g3, %g1, %g1
235	sethi		%hi(FITOS_COMPARE), %g2
236	or		%g2, %lo(FITOS_COMPARE), %g2
237	cmp		%g1, %g2
238	bne,pn		%xcc, do_fptrap_after_fsr
239	 nop
240	std		%f62, [%g6 + TI_FPREGS + (62 * 4)]
241	sethi		%hi(fitos_table_1), %g1
242	and		%g3, 0x1f, %g2
243	or		%g1, %lo(fitos_table_1),  %g1
244	sllx		%g2, 2, %g2
245	jmpl		%g1 + %g2, %g0
246	 ba,pt		%xcc, fitos_emul_continue
247
248fitos_table_1:
249	fitod		%f0, %f62
250	fitod		%f1, %f62
251	fitod		%f2, %f62
252	fitod		%f3, %f62
253	fitod		%f4, %f62
254	fitod		%f5, %f62
255	fitod		%f6, %f62
256	fitod		%f7, %f62
257	fitod		%f8, %f62
258	fitod		%f9, %f62
259	fitod		%f10, %f62
260	fitod		%f11, %f62
261	fitod		%f12, %f62
262	fitod		%f13, %f62
263	fitod		%f14, %f62
264	fitod		%f15, %f62
265	fitod		%f16, %f62
266	fitod		%f17, %f62
267	fitod		%f18, %f62
268	fitod		%f19, %f62
269	fitod		%f20, %f62
270	fitod		%f21, %f62
271	fitod		%f22, %f62
272	fitod		%f23, %f62
273	fitod		%f24, %f62
274	fitod		%f25, %f62
275	fitod		%f26, %f62
276	fitod		%f27, %f62
277	fitod		%f28, %f62
278	fitod		%f29, %f62
279	fitod		%f30, %f62
280	fitod		%f31, %f62
281
282fitos_emul_continue:
283	sethi		%hi(fitos_table_2), %g1
284	srl		%g3, 25, %g2
285	or		%g1, %lo(fitos_table_2), %g1
286	and		%g2, 0x1f, %g2
287	sllx		%g2, 2, %g2
288	jmpl		%g1 + %g2, %g0
289	 ba,pt		%xcc, fitos_emul_fini
290
291fitos_table_2:
292	fdtos		%f62, %f0
293	fdtos		%f62, %f1
294	fdtos		%f62, %f2
295	fdtos		%f62, %f3
296	fdtos		%f62, %f4
297	fdtos		%f62, %f5
298	fdtos		%f62, %f6
299	fdtos		%f62, %f7
300	fdtos		%f62, %f8
301	fdtos		%f62, %f9
302	fdtos		%f62, %f10
303	fdtos		%f62, %f11
304	fdtos		%f62, %f12
305	fdtos		%f62, %f13
306	fdtos		%f62, %f14
307	fdtos		%f62, %f15
308	fdtos		%f62, %f16
309	fdtos		%f62, %f17
310	fdtos		%f62, %f18
311	fdtos		%f62, %f19
312	fdtos		%f62, %f20
313	fdtos		%f62, %f21
314	fdtos		%f62, %f22
315	fdtos		%f62, %f23
316	fdtos		%f62, %f24
317	fdtos		%f62, %f25
318	fdtos		%f62, %f26
319	fdtos		%f62, %f27
320	fdtos		%f62, %f28
321	fdtos		%f62, %f29
322	fdtos		%f62, %f30
323	fdtos		%f62, %f31
324
325fitos_emul_fini:
326	ldd		[%g6 + TI_FPREGS + (62 * 4)], %f62
327	done
328	.size		do_fpother_check_fitos,.-do_fpother_check_fitos
329
330	.align		32
331	.globl		do_fptrap
332	.type		do_fptrap,#function
333do_fptrap:
334	TRAP_LOAD_THREAD_REG(%g6, %g1)
335	stx		%fsr, [%g6 + TI_XFSR]
336do_fptrap_after_fsr:
337	ldub		[%g6 + TI_FPSAVED], %g3
338	rd		%fprs, %g1
339	or		%g3, %g1, %g3
340	stb		%g3, [%g6 + TI_FPSAVED]
341	rd		%gsr, %g3
342	stx		%g3, [%g6 + TI_GSR]
343	mov		SECONDARY_CONTEXT, %g3
344
345661:	ldxa		[%g3] ASI_DMMU, %g5
346	.section	.sun4v_1insn_patch, "ax"
347	.word		661b
348	ldxa		[%g3] ASI_MMU, %g5
349	.previous
350
351	sethi		%hi(sparc64_kern_sec_context), %g2
352	ldx		[%g2 + %lo(sparc64_kern_sec_context)], %g2
353
354661:	stxa		%g2, [%g3] ASI_DMMU
355	.section	.sun4v_1insn_patch, "ax"
356	.word		661b
357	stxa		%g2, [%g3] ASI_MMU
358	.previous
359
360	membar		#Sync
361	add		%g6, TI_FPREGS, %g2
362	andcc		%g1, FPRS_DL, %g0
363	be,pn		%icc, 4f
364	 mov		0x40, %g3
365	stda		%f0, [%g2] ASI_BLK_S
366	stda		%f16, [%g2 + %g3] ASI_BLK_S
367	andcc		%g1, FPRS_DU, %g0
368	be,pn		%icc, 5f
3694:       add		%g2, 128, %g2
370	stda		%f32, [%g2] ASI_BLK_S
371	stda		%f48, [%g2 + %g3] ASI_BLK_S
3725:	mov		SECONDARY_CONTEXT, %g1
373	membar		#Sync
374
375661:	stxa		%g5, [%g1] ASI_DMMU
376	.section	.sun4v_1insn_patch, "ax"
377	.word		661b
378	stxa		%g5, [%g1] ASI_MMU
379	.previous
380
381	membar		#Sync
382	ba,pt		%xcc, etrap
383	 wr		%g0, 0, %fprs
384	.size		do_fptrap,.-do_fptrap
385