1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2b0753902SHendrik Brueckner /*
3b0753902SHendrik Brueckner * FPU state and register content conversion primitives
4b0753902SHendrik Brueckner *
5b0753902SHendrik Brueckner * Copyright IBM Corp. 2015
6b0753902SHendrik Brueckner * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
7b0753902SHendrik Brueckner */
8b0753902SHendrik Brueckner
9b0753902SHendrik Brueckner #ifndef _ASM_S390_FPU_INTERNAL_H
10b0753902SHendrik Brueckner #define _ASM_S390_FPU_INTERNAL_H
11b0753902SHendrik Brueckner
12b0753902SHendrik Brueckner #include <linux/string.h>
13b0753902SHendrik Brueckner #include <asm/ctl_reg.h>
14b0753902SHendrik Brueckner #include <asm/fpu/types.h>
15b0753902SHendrik Brueckner
save_vx_regs(__vector128 * vxrs)161a36a39eSMartin Schwidefsky static inline void save_vx_regs(__vector128 *vxrs)
17b0753902SHendrik Brueckner {
18b0753902SHendrik Brueckner asm volatile(
19b0753902SHendrik Brueckner " la 1,%0\n"
20b0753902SHendrik Brueckner " .word 0xe70f,0x1000,0x003e\n" /* vstm 0,15,0(1) */
21b0753902SHendrik Brueckner " .word 0xe70f,0x1100,0x0c3e\n" /* vstm 16,31,256(1) */
22b0753902SHendrik Brueckner : "=Q" (*(struct vx_array *) vxrs) : : "1");
23b0753902SHendrik Brueckner }
24b0753902SHendrik Brueckner
convert_vx_to_fp(freg_t * fprs,__vector128 * vxrs)25b0753902SHendrik Brueckner static inline void convert_vx_to_fp(freg_t *fprs, __vector128 *vxrs)
26b0753902SHendrik Brueckner {
27b0753902SHendrik Brueckner int i;
28b0753902SHendrik Brueckner
29b0753902SHendrik Brueckner for (i = 0; i < __NUM_FPRS; i++)
30*a02d584eSHeiko Carstens fprs[i].ui = vxrs[i].high;
31b0753902SHendrik Brueckner }
32b0753902SHendrik Brueckner
convert_fp_to_vx(__vector128 * vxrs,freg_t * fprs)33b0753902SHendrik Brueckner static inline void convert_fp_to_vx(__vector128 *vxrs, freg_t *fprs)
34b0753902SHendrik Brueckner {
35b0753902SHendrik Brueckner int i;
36b0753902SHendrik Brueckner
37b0753902SHendrik Brueckner for (i = 0; i < __NUM_FPRS; i++)
38*a02d584eSHeiko Carstens vxrs[i].high = fprs[i].ui;
39b0753902SHendrik Brueckner }
40b0753902SHendrik Brueckner
fpregs_store(_s390_fp_regs * fpregs,struct fpu * fpu)41b0753902SHendrik Brueckner static inline void fpregs_store(_s390_fp_regs *fpregs, struct fpu *fpu)
42b0753902SHendrik Brueckner {
43b0753902SHendrik Brueckner fpregs->pad = 0;
441b17cb79SMartin Schwidefsky fpregs->fpc = fpu->fpc;
45b0753902SHendrik Brueckner if (MACHINE_HAS_VX)
46b0753902SHendrik Brueckner convert_vx_to_fp((freg_t *)&fpregs->fprs, fpu->vxrs);
47b0753902SHendrik Brueckner else
48b0753902SHendrik Brueckner memcpy((freg_t *)&fpregs->fprs, fpu->fprs,
49b0753902SHendrik Brueckner sizeof(fpregs->fprs));
50b0753902SHendrik Brueckner }
51b0753902SHendrik Brueckner
fpregs_load(_s390_fp_regs * fpregs,struct fpu * fpu)52b0753902SHendrik Brueckner static inline void fpregs_load(_s390_fp_regs *fpregs, struct fpu *fpu)
53b0753902SHendrik Brueckner {
541b17cb79SMartin Schwidefsky fpu->fpc = fpregs->fpc;
55b0753902SHendrik Brueckner if (MACHINE_HAS_VX)
56b0753902SHendrik Brueckner convert_fp_to_vx(fpu->vxrs, (freg_t *)&fpregs->fprs);
57b0753902SHendrik Brueckner else
58b0753902SHendrik Brueckner memcpy(fpu->fprs, (freg_t *)&fpregs->fprs,
59b0753902SHendrik Brueckner sizeof(fpregs->fprs));
60b0753902SHendrik Brueckner }
61b0753902SHendrik Brueckner
62b0753902SHendrik Brueckner #endif /* _ASM_S390_FPU_INTERNAL_H */
63