~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/riscv/kernel/fpu.S

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0 */
  2 /*
  3  * Copyright (C) 2012 Regents of the University of California
  4  * Copyright (C) 2017 SiFive
  5  *
  6  *   This program is free software; you can redistribute it and/or
  7  *   modify it under the terms of the GNU General Public License
  8  *   as published by the Free Software Foundation, version 2.
  9  *
 10  *   This program is distributed in the hope that it will be useful,
 11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13  *   GNU General Public License for more details.
 14  */
 15 
 16 #include <linux/linkage.h>
 17 
 18 #include <asm/asm.h>
 19 #include <asm/csr.h>
 20 #include <asm/asm-offsets.h>
 21 
 22 SYM_FUNC_START(__fstate_save)
 23         li  a2,  TASK_THREAD_F0
 24         add a0, a0, a2
 25         li t1, SR_FS
 26         csrs CSR_STATUS, t1
 27         frcsr t0
 28         fsd f0,  TASK_THREAD_F0_F0(a0)
 29         fsd f1,  TASK_THREAD_F1_F0(a0)
 30         fsd f2,  TASK_THREAD_F2_F0(a0)
 31         fsd f3,  TASK_THREAD_F3_F0(a0)
 32         fsd f4,  TASK_THREAD_F4_F0(a0)
 33         fsd f5,  TASK_THREAD_F5_F0(a0)
 34         fsd f6,  TASK_THREAD_F6_F0(a0)
 35         fsd f7,  TASK_THREAD_F7_F0(a0)
 36         fsd f8,  TASK_THREAD_F8_F0(a0)
 37         fsd f9,  TASK_THREAD_F9_F0(a0)
 38         fsd f10, TASK_THREAD_F10_F0(a0)
 39         fsd f11, TASK_THREAD_F11_F0(a0)
 40         fsd f12, TASK_THREAD_F12_F0(a0)
 41         fsd f13, TASK_THREAD_F13_F0(a0)
 42         fsd f14, TASK_THREAD_F14_F0(a0)
 43         fsd f15, TASK_THREAD_F15_F0(a0)
 44         fsd f16, TASK_THREAD_F16_F0(a0)
 45         fsd f17, TASK_THREAD_F17_F0(a0)
 46         fsd f18, TASK_THREAD_F18_F0(a0)
 47         fsd f19, TASK_THREAD_F19_F0(a0)
 48         fsd f20, TASK_THREAD_F20_F0(a0)
 49         fsd f21, TASK_THREAD_F21_F0(a0)
 50         fsd f22, TASK_THREAD_F22_F0(a0)
 51         fsd f23, TASK_THREAD_F23_F0(a0)
 52         fsd f24, TASK_THREAD_F24_F0(a0)
 53         fsd f25, TASK_THREAD_F25_F0(a0)
 54         fsd f26, TASK_THREAD_F26_F0(a0)
 55         fsd f27, TASK_THREAD_F27_F0(a0)
 56         fsd f28, TASK_THREAD_F28_F0(a0)
 57         fsd f29, TASK_THREAD_F29_F0(a0)
 58         fsd f30, TASK_THREAD_F30_F0(a0)
 59         fsd f31, TASK_THREAD_F31_F0(a0)
 60         sw t0, TASK_THREAD_FCSR_F0(a0)
 61         csrc CSR_STATUS, t1
 62         ret
 63 SYM_FUNC_END(__fstate_save)
 64 
 65 SYM_FUNC_START(__fstate_restore)
 66         li  a2,  TASK_THREAD_F0
 67         add a0, a0, a2
 68         li t1, SR_FS
 69         lw t0, TASK_THREAD_FCSR_F0(a0)
 70         csrs CSR_STATUS, t1
 71         fld f0,  TASK_THREAD_F0_F0(a0)
 72         fld f1,  TASK_THREAD_F1_F0(a0)
 73         fld f2,  TASK_THREAD_F2_F0(a0)
 74         fld f3,  TASK_THREAD_F3_F0(a0)
 75         fld f4,  TASK_THREAD_F4_F0(a0)
 76         fld f5,  TASK_THREAD_F5_F0(a0)
 77         fld f6,  TASK_THREAD_F6_F0(a0)
 78         fld f7,  TASK_THREAD_F7_F0(a0)
 79         fld f8,  TASK_THREAD_F8_F0(a0)
 80         fld f9,  TASK_THREAD_F9_F0(a0)
 81         fld f10, TASK_THREAD_F10_F0(a0)
 82         fld f11, TASK_THREAD_F11_F0(a0)
 83         fld f12, TASK_THREAD_F12_F0(a0)
 84         fld f13, TASK_THREAD_F13_F0(a0)
 85         fld f14, TASK_THREAD_F14_F0(a0)
 86         fld f15, TASK_THREAD_F15_F0(a0)
 87         fld f16, TASK_THREAD_F16_F0(a0)
 88         fld f17, TASK_THREAD_F17_F0(a0)
 89         fld f18, TASK_THREAD_F18_F0(a0)
 90         fld f19, TASK_THREAD_F19_F0(a0)
 91         fld f20, TASK_THREAD_F20_F0(a0)
 92         fld f21, TASK_THREAD_F21_F0(a0)
 93         fld f22, TASK_THREAD_F22_F0(a0)
 94         fld f23, TASK_THREAD_F23_F0(a0)
 95         fld f24, TASK_THREAD_F24_F0(a0)
 96         fld f25, TASK_THREAD_F25_F0(a0)
 97         fld f26, TASK_THREAD_F26_F0(a0)
 98         fld f27, TASK_THREAD_F27_F0(a0)
 99         fld f28, TASK_THREAD_F28_F0(a0)
100         fld f29, TASK_THREAD_F29_F0(a0)
101         fld f30, TASK_THREAD_F30_F0(a0)
102         fld f31, TASK_THREAD_F31_F0(a0)
103         fscsr t0
104         csrc CSR_STATUS, t1
105         ret
106 SYM_FUNC_END(__fstate_restore)
107 
108 #define get_f32(which) fmv.x.s a0, which; j 2f
109 #define put_f32(which) fmv.s.x which, a1; j 2f
110 #if __riscv_xlen == 64
111 # define get_f64(which) fmv.x.d a0, which; j 2f
112 # define put_f64(which) fmv.d.x which, a1; j 2f
113 #else
114 # define get_f64(which) fsd which, 0(a1); j 2f
115 # define put_f64(which) fld which, 0(a1); j 2f
116 #endif
117 
118 .macro fp_access_prologue
119         /*
120          * Compute jump offset to store the correct FP register since we don't
121          * have indirect FP register access
122          */
123         sll t0, a0, 3
124         la t2, 1f
125         add t0, t0, t2
126         li t1, SR_FS
127         csrs CSR_STATUS, t1
128         jr t0
129 1:
130 .endm
131 
132 .macro fp_access_epilogue
133 2:
134         csrc CSR_STATUS, t1
135         ret
136 .endm
137 
138 #define fp_access_body(__access_func) \
139         __access_func(f0); \
140         __access_func(f1); \
141         __access_func(f2); \
142         __access_func(f3); \
143         __access_func(f4); \
144         __access_func(f5); \
145         __access_func(f6); \
146         __access_func(f7); \
147         __access_func(f8); \
148         __access_func(f9); \
149         __access_func(f10); \
150         __access_func(f11); \
151         __access_func(f12); \
152         __access_func(f13); \
153         __access_func(f14); \
154         __access_func(f15); \
155         __access_func(f16); \
156         __access_func(f17); \
157         __access_func(f18); \
158         __access_func(f19); \
159         __access_func(f20); \
160         __access_func(f21); \
161         __access_func(f22); \
162         __access_func(f23); \
163         __access_func(f24); \
164         __access_func(f25); \
165         __access_func(f26); \
166         __access_func(f27); \
167         __access_func(f28); \
168         __access_func(f29); \
169         __access_func(f30); \
170         __access_func(f31)
171 
172 
173 #ifdef CONFIG_RISCV_MISALIGNED
174 
175 /*
176  * Disable compressed instructions set to keep a constant offset between FP
177  * load/store/move instructions
178  */
179 .option norvc
180 /*
181  * put_f32_reg - Set a FP register from a register containing the value
182  * a0 = FP register index to be set
183  * a1 = value to be loaded in the FP register
184  */
185 SYM_FUNC_START(put_f32_reg)
186         fp_access_prologue
187         fp_access_body(put_f32)
188         fp_access_epilogue
189 SYM_FUNC_END(put_f32_reg)
190 
191 /*
192  * get_f32_reg - Get a FP register value and return it
193  * a0 = FP register index to be retrieved
194  */
195 SYM_FUNC_START(get_f32_reg)
196         fp_access_prologue
197         fp_access_body(get_f32)
198         fp_access_epilogue
199 SYM_FUNC_END(get_f32_reg)
200 
201 /*
202  * put_f64_reg - Set a 64 bits FP register from a value or a pointer.
203  * a0 = FP register index to be set
204  * a1 = value/pointer to be loaded in the FP register (when xlen == 32 bits, we
205  * load the value to a pointer).
206  */
207 SYM_FUNC_START(put_f64_reg)
208         fp_access_prologue
209         fp_access_body(put_f64)
210         fp_access_epilogue
211 SYM_FUNC_END(put_f64_reg)
212 
213 /*
214  * get_f64_reg - Get a 64 bits FP register value and returned it or store it to
215  *               a pointer.
216  * a0 = FP register index to be retrieved
217  * a1 = If xlen == 32, pointer which should be loaded with the FP register value
218  *      or unused if xlen == 64. In which case the FP register value is returned
219  *      through a0
220  */
221 SYM_FUNC_START(get_f64_reg)
222         fp_access_prologue
223         fp_access_body(get_f64)
224         fp_access_epilogue
225 SYM_FUNC_END(get_f64_reg)
226 
227 #endif /* CONFIG_RISCV_MISALIGNED */

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php