Linux-libre 4.14.145-gnu
[librecmc/linux-libre.git] / arch / mips / kernel / r2300_fpu.S
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 1996, 1998 by Ralf Baechle
7  *
8  * Multi-arch abstraction and asm macros for easier reading:
9  * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
10  *
11  * Further modifications to make this work:
12  * Copyright (c) 1998 Harald Koerfgen
13  */
14 #include <asm/asm.h>
15 #include <asm/asmmacro.h>
16 #include <asm/errno.h>
17 #include <asm/export.h>
18 #include <asm/fpregdef.h>
19 #include <asm/mipsregs.h>
20 #include <asm/asm-offsets.h>
21 #include <asm/regdef.h>
22
23 #define EX(a,b)                                                 \
24 9:      a,##b;                                                  \
25         .section __ex_table,"a";                                \
26         PTR     9b,fault;                                       \
27         .previous
28
29 #define EX2(a,b)                                                \
30 9:      a,##b;                                                  \
31         .section __ex_table,"a";                                \
32         PTR     9b,bad_stack;                                   \
33         PTR     9b+4,bad_stack;                                 \
34         .previous
35
36         .set    mips1
37
38 /*
39  * Save a thread's fp context.
40  */
41 LEAF(_save_fp)
42 EXPORT_SYMBOL(_save_fp)
43         fpu_save_single a0, t1                  # clobbers t1
44         jr      ra
45         END(_save_fp)
46
47 /*
48  * Restore a thread's fp context.
49  */
50 LEAF(_restore_fp)
51         fpu_restore_single a0, t1               # clobbers t1
52         jr      ra
53         END(_restore_fp)
54
55 /*
56  * Load the FPU with signalling NANS.  This bit pattern we're using has
57  * the property that no matter whether considered as single or as double
58  * precision represents signaling NANS.
59  *
60  * The value to initialize fcr31 to comes in $a0.
61  */
62
63         .set push
64         SET_HARDFLOAT
65
66 LEAF(_init_fpu)
67         mfc0    t0, CP0_STATUS
68         li      t1, ST0_CU1
69         or      t0, t1
70         mtc0    t0, CP0_STATUS
71
72         ctc1    a0, fcr31
73
74         li      t0, -1
75
76         mtc1    t0, $f0
77         mtc1    t0, $f1
78         mtc1    t0, $f2
79         mtc1    t0, $f3
80         mtc1    t0, $f4
81         mtc1    t0, $f5
82         mtc1    t0, $f6
83         mtc1    t0, $f7
84         mtc1    t0, $f8
85         mtc1    t0, $f9
86         mtc1    t0, $f10
87         mtc1    t0, $f11
88         mtc1    t0, $f12
89         mtc1    t0, $f13
90         mtc1    t0, $f14
91         mtc1    t0, $f15
92         mtc1    t0, $f16
93         mtc1    t0, $f17
94         mtc1    t0, $f18
95         mtc1    t0, $f19
96         mtc1    t0, $f20
97         mtc1    t0, $f21
98         mtc1    t0, $f22
99         mtc1    t0, $f23
100         mtc1    t0, $f24
101         mtc1    t0, $f25
102         mtc1    t0, $f26
103         mtc1    t0, $f27
104         mtc1    t0, $f28
105         mtc1    t0, $f29
106         mtc1    t0, $f30
107         mtc1    t0, $f31
108         jr      ra
109         END(_init_fpu)
110
111         .set pop
112
113         .set    noreorder
114
115 /**
116  * _save_fp_context() - save FP context from the FPU
117  * @a0 - pointer to fpregs field of sigcontext
118  * @a1 - pointer to fpc_csr field of sigcontext
119  *
120  * Save FP context, including the 32 FP data registers and the FP
121  * control & status register, from the FPU to signal context.
122  */
123 LEAF(_save_fp_context)
124         .set    push
125         SET_HARDFLOAT
126         li      v0, 0                                   # assume success
127         cfc1    t1, fcr31
128         EX2(s.d $f0, 0(a0))
129         EX2(s.d $f2, 16(a0))
130         EX2(s.d $f4, 32(a0))
131         EX2(s.d $f6, 48(a0))
132         EX2(s.d $f8, 64(a0))
133         EX2(s.d $f10, 80(a0))
134         EX2(s.d $f12, 96(a0))
135         EX2(s.d $f14, 112(a0))
136         EX2(s.d $f16, 128(a0))
137         EX2(s.d $f18, 144(a0))
138         EX2(s.d $f20, 160(a0))
139         EX2(s.d $f22, 176(a0))
140         EX2(s.d $f24, 192(a0))
141         EX2(s.d $f26, 208(a0))
142         EX2(s.d $f28, 224(a0))
143         EX2(s.d $f30, 240(a0))
144         jr      ra
145          EX(sw  t1, (a1))
146         .set    pop
147         END(_save_fp_context)
148
149 /**
150  * _restore_fp_context() - restore FP context to the FPU
151  * @a0 - pointer to fpregs field of sigcontext
152  * @a1 - pointer to fpc_csr field of sigcontext
153  *
154  * Restore FP context, including the 32 FP data registers and the FP
155  * control & status register, from signal context to the FPU.
156  */
157 LEAF(_restore_fp_context)
158         .set    push
159         SET_HARDFLOAT
160         li      v0, 0                                   # assume success
161         EX(lw t0, (a1))
162         EX2(l.d $f0, 0(a0))
163         EX2(l.d $f2, 16(a0))
164         EX2(l.d $f4, 32(a0))
165         EX2(l.d $f6, 48(a0))
166         EX2(l.d $f8, 64(a0))
167         EX2(l.d $f10, 80(a0))
168         EX2(l.d $f12, 96(a0))
169         EX2(l.d $f14, 112(a0))
170         EX2(l.d $f16, 128(a0))
171         EX2(l.d $f18, 144(a0))
172         EX2(l.d $f20, 160(a0))
173         EX2(l.d $f22, 176(a0))
174         EX2(l.d $f24, 192(a0))
175         EX2(l.d $f26, 208(a0))
176         EX2(l.d $f28, 224(a0))
177         EX2(l.d $f30, 240(a0))
178         jr      ra
179          ctc1   t0, fcr31
180         .set    pop
181         END(_restore_fp_context)
182         .set    reorder
183
184         .type   fault, @function
185         .ent    fault
186 fault:  li      v0, -EFAULT
187         jr      ra
188         .end    fault