18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef _SPARC64_VISASM_H
38c2ecf20Sopenharmony_ci#define _SPARC64_VISASM_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci/* visasm.h:  FPU saving macros for VIS routines
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <asm/pstate.h>
118c2ecf20Sopenharmony_ci#include <asm/ptrace.h>
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci/* Clobbers %o5, %g1, %g2, %g3, %g7, %icc, %xcc */
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#define VISEntry					\
168c2ecf20Sopenharmony_ci	rd		%fprs, %o5;			\
178c2ecf20Sopenharmony_ci	andcc		%o5, (FPRS_FEF|FPRS_DU), %g0;	\
188c2ecf20Sopenharmony_ci	be,pt		%icc, 297f;			\
198c2ecf20Sopenharmony_ci	 sethi		%hi(297f), %g7;			\
208c2ecf20Sopenharmony_ci	sethi		%hi(VISenter), %g1;		\
218c2ecf20Sopenharmony_ci	jmpl		%g1 + %lo(VISenter), %g0;	\
228c2ecf20Sopenharmony_ci	 or		%g7, %lo(297f), %g7;		\
238c2ecf20Sopenharmony_ci297:	wr		%g0, FPRS_FEF, %fprs;		\
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci#define VISExit						\
268c2ecf20Sopenharmony_ci	wr		%g0, 0, %fprs;
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci/* Clobbers %o5, %g1, %g2, %g3, %g7, %icc, %xcc.
298c2ecf20Sopenharmony_ci * Must preserve %o5 between VISEntryHalf and VISExitHalf */
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci#define VISEntryHalf					\
328c2ecf20Sopenharmony_ci	VISEntry
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci#define VISExitHalf					\
358c2ecf20Sopenharmony_ci	VISExit
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci#define VISEntryHalfFast(fail_label)			\
388c2ecf20Sopenharmony_ci	rd		%fprs, %o5;			\
398c2ecf20Sopenharmony_ci	andcc		%o5, FPRS_FEF, %g0;		\
408c2ecf20Sopenharmony_ci	be,pt		%icc, 297f;			\
418c2ecf20Sopenharmony_ci	 nop;						\
428c2ecf20Sopenharmony_ci	ba,a,pt		%xcc, fail_label;		\
438c2ecf20Sopenharmony_ci297:	wr		%o5, FPRS_FEF, %fprs;
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci#define VISExitHalfFast					\
468c2ecf20Sopenharmony_ci	wr		%o5, 0, %fprs;
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__
498c2ecf20Sopenharmony_cistatic inline void save_and_clear_fpu(void) {
508c2ecf20Sopenharmony_ci	__asm__ __volatile__ (
518c2ecf20Sopenharmony_ci"		rd %%fprs, %%o5\n"
528c2ecf20Sopenharmony_ci"		andcc %%o5, %0, %%g0\n"
538c2ecf20Sopenharmony_ci"		be,pt %%icc, 299f\n"
548c2ecf20Sopenharmony_ci"		 sethi %%hi(298f), %%g7\n"
558c2ecf20Sopenharmony_ci"		sethi %%hi(VISenter), %%g1\n"
568c2ecf20Sopenharmony_ci"		jmpl %%g1 + %%lo(VISenter), %%g0\n"
578c2ecf20Sopenharmony_ci"		 or %%g7, %%lo(298f), %%g7\n"
588c2ecf20Sopenharmony_ci"	298:	wr %%g0, 0, %%fprs\n"
598c2ecf20Sopenharmony_ci"	299:\n"
608c2ecf20Sopenharmony_ci"		" : : "i" (FPRS_FEF|FPRS_DU) :
618c2ecf20Sopenharmony_ci		"o5", "g1", "g2", "g3", "g7", "cc");
628c2ecf20Sopenharmony_ci}
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ciint vis_emul(struct pt_regs *, unsigned int);
658c2ecf20Sopenharmony_ci#endif
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci#endif /* _SPARC64_ASI_H */
68