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