1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * Author: Lu Zeng <zenglu@loongson.cn> 4 * Pei Huang <huangpei@loongson.cn> 5 * Huacai Chen <chenhuacai@loongson.cn> 6 * 7 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 8 */ 9#include <linux/export.h> 10#include <asm/asm.h> 11#include <asm/asmmacro.h> 12#include <asm/asm-extable.h> 13#include <asm/asm-offsets.h> 14#include <asm/errno.h> 15#include <asm/fpregdef.h> 16#include <asm/loongarch.h> 17#include <asm/regdef.h> 18#include <asm/unwind_hints.h> 19 20#define FPU_REG_WIDTH 8 21#define LSX_REG_WIDTH 16 22#define LASX_REG_WIDTH 32 23 24 .macro EX insn, reg, src, offs 25.ex\@: \insn \reg, \src, \offs 26 _asm_extable .ex\@, .L_fpu_fault 27 .endm 28 29 .macro sc_save_fp base 30 EX fst.d $f0, \base, (0 * FPU_REG_WIDTH) 31 EX fst.d $f1, \base, (1 * FPU_REG_WIDTH) 32 EX fst.d $f2, \base, (2 * FPU_REG_WIDTH) 33 EX fst.d $f3, \base, (3 * FPU_REG_WIDTH) 34 EX fst.d $f4, \base, (4 * FPU_REG_WIDTH) 35 EX fst.d $f5, \base, (5 * FPU_REG_WIDTH) 36 EX fst.d $f6, \base, (6 * FPU_REG_WIDTH) 37 EX fst.d $f7, \base, (7 * FPU_REG_WIDTH) 38 EX fst.d $f8, \base, (8 * FPU_REG_WIDTH) 39 EX fst.d $f9, \base, (9 * FPU_REG_WIDTH) 40 EX fst.d $f10, \base, (10 * FPU_REG_WIDTH) 41 EX fst.d $f11, \base, (11 * FPU_REG_WIDTH) 42 EX fst.d $f12, \base, (12 * FPU_REG_WIDTH) 43 EX fst.d $f13, \base, (13 * FPU_REG_WIDTH) 44 EX fst.d $f14, \base, (14 * FPU_REG_WIDTH) 45 EX fst.d $f15, \base, (15 * FPU_REG_WIDTH) 46 EX fst.d $f16, \base, (16 * FPU_REG_WIDTH) 47 EX fst.d $f17, \base, (17 * FPU_REG_WIDTH) 48 EX fst.d $f18, \base, (18 * FPU_REG_WIDTH) 49 EX fst.d $f19, \base, (19 * FPU_REG_WIDTH) 50 EX fst.d $f20, \base, (20 * FPU_REG_WIDTH) 51 EX fst.d $f21, \base, (21 * FPU_REG_WIDTH) 52 EX fst.d $f22, \base, (22 * FPU_REG_WIDTH) 53 EX fst.d $f23, \base, (23 * FPU_REG_WIDTH) 54 EX fst.d $f24, \base, (24 * FPU_REG_WIDTH) 55 EX fst.d $f25, \base, (25 * FPU_REG_WIDTH) 56 EX fst.d $f26, \base, (26 * FPU_REG_WIDTH) 57 EX fst.d $f27, \base, (27 * FPU_REG_WIDTH) 58 EX fst.d $f28, \base, (28 * FPU_REG_WIDTH) 59 EX fst.d $f29, \base, (29 * FPU_REG_WIDTH) 60 EX fst.d $f30, \base, (30 * FPU_REG_WIDTH) 61 EX fst.d $f31, \base, (31 * FPU_REG_WIDTH) 62 .endm 63 64 .macro sc_restore_fp base 65 EX fld.d $f0, \base, (0 * FPU_REG_WIDTH) 66 EX fld.d $f1, \base, (1 * FPU_REG_WIDTH) 67 EX fld.d $f2, \base, (2 * FPU_REG_WIDTH) 68 EX fld.d $f3, \base, (3 * FPU_REG_WIDTH) 69 EX fld.d $f4, \base, (4 * FPU_REG_WIDTH) 70 EX fld.d $f5, \base, (5 * FPU_REG_WIDTH) 71 EX fld.d $f6, \base, (6 * FPU_REG_WIDTH) 72 EX fld.d $f7, \base, (7 * FPU_REG_WIDTH) 73 EX fld.d $f8, \base, (8 * FPU_REG_WIDTH) 74 EX fld.d $f9, \base, (9 * FPU_REG_WIDTH) 75 EX fld.d $f10, \base, (10 * FPU_REG_WIDTH) 76 EX fld.d $f11, \base, (11 * FPU_REG_WIDTH) 77 EX fld.d $f12, \base, (12 * FPU_REG_WIDTH) 78 EX fld.d $f13, \base, (13 * FPU_REG_WIDTH) 79 EX fld.d $f14, \base, (14 * FPU_REG_WIDTH) 80 EX fld.d $f15, \base, (15 * FPU_REG_WIDTH) 81 EX fld.d $f16, \base, (16 * FPU_REG_WIDTH) 82 EX fld.d $f17, \base, (17 * FPU_REG_WIDTH) 83 EX fld.d $f18, \base, (18 * FPU_REG_WIDTH) 84 EX fld.d $f19, \base, (19 * FPU_REG_WIDTH) 85 EX fld.d $f20, \base, (20 * FPU_REG_WIDTH) 86 EX fld.d $f21, \base, (21 * FPU_REG_WIDTH) 87 EX fld.d $f22, \base, (22 * FPU_REG_WIDTH) 88 EX fld.d $f23, \base, (23 * FPU_REG_WIDTH) 89 EX fld.d $f24, \base, (24 * FPU_REG_WIDTH) 90 EX fld.d $f25, \base, (25 * FPU_REG_WIDTH) 91 EX fld.d $f26, \base, (26 * FPU_REG_WIDTH) 92 EX fld.d $f27, \base, (27 * FPU_REG_WIDTH) 93 EX fld.d $f28, \base, (28 * FPU_REG_WIDTH) 94 EX fld.d $f29, \base, (29 * FPU_REG_WIDTH) 95 EX fld.d $f30, \base, (30 * FPU_REG_WIDTH) 96 EX fld.d $f31, \base, (31 * FPU_REG_WIDTH) 97 .endm 98 99#ifdef CONFIG_32BIT 100 .macro sc_save_fcc thread tmp0 tmp1 101 movcf2gr \tmp0, $fcc0 102 move \tmp1, \tmp0 103 movcf2gr \tmp0, $fcc1 104 bstrins.w \tmp1, \tmp0, 15, 8 105 movcf2gr \tmp0, $fcc2 106 bstrins.w \tmp1, \tmp0, 23, 16 107 movcf2gr \tmp0, $fcc3 108 bstrins.w \tmp1, \tmp0, 31, 24 109 EX st.w \tmp1, \thread, THREAD_FCC 110 movcf2gr \tmp0, $fcc4 111 move \tmp1, \tmp0 112 movcf2gr \tmp0, $fcc5 113 bstrins.w \tmp1, \tmp0, 15, 8 114 movcf2gr \tmp0, $fcc6 115 bstrins.w \tmp1, \tmp0, 23, 16 116 movcf2gr \tmp0, $fcc7 117 bstrins.w \tmp1, \tmp0, 31, 24 118 EX st.w \tmp1, \thread, (THREAD_FCC + 4) 119 .endm 120 121 .macro sc_restore_fcc thread tmp0 tmp1 122 EX ld.w \tmp0, \thread, THREAD_FCC 123 bstrpick.w \tmp1, \tmp0, 7, 0 124 movgr2cf $fcc0, \tmp1 125 bstrpick.w \tmp1, \tmp0, 15, 8 126 movgr2cf $fcc1, \tmp1 127 bstrpick.w \tmp1, \tmp0, 23, 16 128 movgr2cf $fcc2, \tmp1 129 bstrpick.w \tmp1, \tmp0, 31, 24 130 movgr2cf $fcc3, \tmp1 131 EX ld.w \tmp0, \thread, (THREAD_FCC + 4) 132 bstrpick.w \tmp1, \tmp0, 7, 0 133 movgr2cf $fcc4, \tmp1 134 bstrpick.w \tmp1, \tmp0, 15, 8 135 movgr2cf $fcc5, \tmp1 136 bstrpick.w \tmp1, \tmp0, 23, 16 137 movgr2cf $fcc6, \tmp1 138 bstrpick.w \tmp1, \tmp0, 31, 24 139 movgr2cf $fcc7, \tmp1 140 .endm 141#else 142 .macro sc_save_fcc base, tmp0, tmp1 143 movcf2gr \tmp0, $fcc0 144 move \tmp1, \tmp0 145 movcf2gr \tmp0, $fcc1 146 bstrins.d \tmp1, \tmp0, 15, 8 147 movcf2gr \tmp0, $fcc2 148 bstrins.d \tmp1, \tmp0, 23, 16 149 movcf2gr \tmp0, $fcc3 150 bstrins.d \tmp1, \tmp0, 31, 24 151 movcf2gr \tmp0, $fcc4 152 bstrins.d \tmp1, \tmp0, 39, 32 153 movcf2gr \tmp0, $fcc5 154 bstrins.d \tmp1, \tmp0, 47, 40 155 movcf2gr \tmp0, $fcc6 156 bstrins.d \tmp1, \tmp0, 55, 48 157 movcf2gr \tmp0, $fcc7 158 bstrins.d \tmp1, \tmp0, 63, 56 159 EX st.d \tmp1, \base, 0 160 .endm 161 162 .macro sc_restore_fcc base, tmp0, tmp1 163 EX ld.d \tmp0, \base, 0 164 bstrpick.d \tmp1, \tmp0, 7, 0 165 movgr2cf $fcc0, \tmp1 166 bstrpick.d \tmp1, \tmp0, 15, 8 167 movgr2cf $fcc1, \tmp1 168 bstrpick.d \tmp1, \tmp0, 23, 16 169 movgr2cf $fcc2, \tmp1 170 bstrpick.d \tmp1, \tmp0, 31, 24 171 movgr2cf $fcc3, \tmp1 172 bstrpick.d \tmp1, \tmp0, 39, 32 173 movgr2cf $fcc4, \tmp1 174 bstrpick.d \tmp1, \tmp0, 47, 40 175 movgr2cf $fcc5, \tmp1 176 bstrpick.d \tmp1, \tmp0, 55, 48 177 movgr2cf $fcc6, \tmp1 178 bstrpick.d \tmp1, \tmp0, 63, 56 179 movgr2cf $fcc7, \tmp1 180 .endm 181#endif 182 183 .macro sc_save_fcsr base, tmp0 184 movfcsr2gr \tmp0, fcsr0 185 EX st.w \tmp0, \base, 0 186#if defined(CONFIG_CPU_HAS_LBT) 187 /* TM bit is always 0 if LBT not supported */ 188 andi \tmp0, \tmp0, FPU_CSR_TM 189 beqz \tmp0, 1f 190 x86clrtm 1911: 192#endif 193 .endm 194 195 .macro sc_restore_fcsr base, tmp0 196 EX ld.w \tmp0, \base, 0 197 movgr2fcsr fcsr0, \tmp0 198 .endm 199 200 .macro sc_save_lsx base 201#ifdef CONFIG_CPU_HAS_LSX 202 EX vst $vr0, \base, (0 * LSX_REG_WIDTH) 203 EX vst $vr1, \base, (1 * LSX_REG_WIDTH) 204 EX vst $vr2, \base, (2 * LSX_REG_WIDTH) 205 EX vst $vr3, \base, (3 * LSX_REG_WIDTH) 206 EX vst $vr4, \base, (4 * LSX_REG_WIDTH) 207 EX vst $vr5, \base, (5 * LSX_REG_WIDTH) 208 EX vst $vr6, \base, (6 * LSX_REG_WIDTH) 209 EX vst $vr7, \base, (7 * LSX_REG_WIDTH) 210 EX vst $vr8, \base, (8 * LSX_REG_WIDTH) 211 EX vst $vr9, \base, (9 * LSX_REG_WIDTH) 212 EX vst $vr10, \base, (10 * LSX_REG_WIDTH) 213 EX vst $vr11, \base, (11 * LSX_REG_WIDTH) 214 EX vst $vr12, \base, (12 * LSX_REG_WIDTH) 215 EX vst $vr13, \base, (13 * LSX_REG_WIDTH) 216 EX vst $vr14, \base, (14 * LSX_REG_WIDTH) 217 EX vst $vr15, \base, (15 * LSX_REG_WIDTH) 218 EX vst $vr16, \base, (16 * LSX_REG_WIDTH) 219 EX vst $vr17, \base, (17 * LSX_REG_WIDTH) 220 EX vst $vr18, \base, (18 * LSX_REG_WIDTH) 221 EX vst $vr19, \base, (19 * LSX_REG_WIDTH) 222 EX vst $vr20, \base, (20 * LSX_REG_WIDTH) 223 EX vst $vr21, \base, (21 * LSX_REG_WIDTH) 224 EX vst $vr22, \base, (22 * LSX_REG_WIDTH) 225 EX vst $vr23, \base, (23 * LSX_REG_WIDTH) 226 EX vst $vr24, \base, (24 * LSX_REG_WIDTH) 227 EX vst $vr25, \base, (25 * LSX_REG_WIDTH) 228 EX vst $vr26, \base, (26 * LSX_REG_WIDTH) 229 EX vst $vr27, \base, (27 * LSX_REG_WIDTH) 230 EX vst $vr28, \base, (28 * LSX_REG_WIDTH) 231 EX vst $vr29, \base, (29 * LSX_REG_WIDTH) 232 EX vst $vr30, \base, (30 * LSX_REG_WIDTH) 233 EX vst $vr31, \base, (31 * LSX_REG_WIDTH) 234#endif 235 .endm 236 237 .macro sc_restore_lsx base 238#ifdef CONFIG_CPU_HAS_LSX 239 EX vld $vr0, \base, (0 * LSX_REG_WIDTH) 240 EX vld $vr1, \base, (1 * LSX_REG_WIDTH) 241 EX vld $vr2, \base, (2 * LSX_REG_WIDTH) 242 EX vld $vr3, \base, (3 * LSX_REG_WIDTH) 243 EX vld $vr4, \base, (4 * LSX_REG_WIDTH) 244 EX vld $vr5, \base, (5 * LSX_REG_WIDTH) 245 EX vld $vr6, \base, (6 * LSX_REG_WIDTH) 246 EX vld $vr7, \base, (7 * LSX_REG_WIDTH) 247 EX vld $vr8, \base, (8 * LSX_REG_WIDTH) 248 EX vld $vr9, \base, (9 * LSX_REG_WIDTH) 249 EX vld $vr10, \base, (10 * LSX_REG_WIDTH) 250 EX vld $vr11, \base, (11 * LSX_REG_WIDTH) 251 EX vld $vr12, \base, (12 * LSX_REG_WIDTH) 252 EX vld $vr13, \base, (13 * LSX_REG_WIDTH) 253 EX vld $vr14, \base, (14 * LSX_REG_WIDTH) 254 EX vld $vr15, \base, (15 * LSX_REG_WIDTH) 255 EX vld $vr16, \base, (16 * LSX_REG_WIDTH) 256 EX vld $vr17, \base, (17 * LSX_REG_WIDTH) 257 EX vld $vr18, \base, (18 * LSX_REG_WIDTH) 258 EX vld $vr19, \base, (19 * LSX_REG_WIDTH) 259 EX vld $vr20, \base, (20 * LSX_REG_WIDTH) 260 EX vld $vr21, \base, (21 * LSX_REG_WIDTH) 261 EX vld $vr22, \base, (22 * LSX_REG_WIDTH) 262 EX vld $vr23, \base, (23 * LSX_REG_WIDTH) 263 EX vld $vr24, \base, (24 * LSX_REG_WIDTH) 264 EX vld $vr25, \base, (25 * LSX_REG_WIDTH) 265 EX vld $vr26, \base, (26 * LSX_REG_WIDTH) 266 EX vld $vr27, \base, (27 * LSX_REG_WIDTH) 267 EX vld $vr28, \base, (28 * LSX_REG_WIDTH) 268 EX vld $vr29, \base, (29 * LSX_REG_WIDTH) 269 EX vld $vr30, \base, (30 * LSX_REG_WIDTH) 270 EX vld $vr31, \base, (31 * LSX_REG_WIDTH) 271#endif 272 .endm 273 274 .macro sc_save_lasx base 275#ifdef CONFIG_CPU_HAS_LASX 276 EX xvst $xr0, \base, (0 * LASX_REG_WIDTH) 277 EX xvst $xr1, \base, (1 * LASX_REG_WIDTH) 278 EX xvst $xr2, \base, (2 * LASX_REG_WIDTH) 279 EX xvst $xr3, \base, (3 * LASX_REG_WIDTH) 280 EX xvst $xr4, \base, (4 * LASX_REG_WIDTH) 281 EX xvst $xr5, \base, (5 * LASX_REG_WIDTH) 282 EX xvst $xr6, \base, (6 * LASX_REG_WIDTH) 283 EX xvst $xr7, \base, (7 * LASX_REG_WIDTH) 284 EX xvst $xr8, \base, (8 * LASX_REG_WIDTH) 285 EX xvst $xr9, \base, (9 * LASX_REG_WIDTH) 286 EX xvst $xr10, \base, (10 * LASX_REG_WIDTH) 287 EX xvst $xr11, \base, (11 * LASX_REG_WIDTH) 288 EX xvst $xr12, \base, (12 * LASX_REG_WIDTH) 289 EX xvst $xr13, \base, (13 * LASX_REG_WIDTH) 290 EX xvst $xr14, \base, (14 * LASX_REG_WIDTH) 291 EX xvst $xr15, \base, (15 * LASX_REG_WIDTH) 292 EX xvst $xr16, \base, (16 * LASX_REG_WIDTH) 293 EX xvst $xr17, \base, (17 * LASX_REG_WIDTH) 294 EX xvst $xr18, \base, (18 * LASX_REG_WIDTH) 295 EX xvst $xr19, \base, (19 * LASX_REG_WIDTH) 296 EX xvst $xr20, \base, (20 * LASX_REG_WIDTH) 297 EX xvst $xr21, \base, (21 * LASX_REG_WIDTH) 298 EX xvst $xr22, \base, (22 * LASX_REG_WIDTH) 299 EX xvst $xr23, \base, (23 * LASX_REG_WIDTH) 300 EX xvst $xr24, \base, (24 * LASX_REG_WIDTH) 301 EX xvst $xr25, \base, (25 * LASX_REG_WIDTH) 302 EX xvst $xr26, \base, (26 * LASX_REG_WIDTH) 303 EX xvst $xr27, \base, (27 * LASX_REG_WIDTH) 304 EX xvst $xr28, \base, (28 * LASX_REG_WIDTH) 305 EX xvst $xr29, \base, (29 * LASX_REG_WIDTH) 306 EX xvst $xr30, \base, (30 * LASX_REG_WIDTH) 307 EX xvst $xr31, \base, (31 * LASX_REG_WIDTH) 308#endif 309 .endm 310 311 .macro sc_restore_lasx base 312#ifdef CONFIG_CPU_HAS_LASX 313 EX xvld $xr0, \base, (0 * LASX_REG_WIDTH) 314 EX xvld $xr1, \base, (1 * LASX_REG_WIDTH) 315 EX xvld $xr2, \base, (2 * LASX_REG_WIDTH) 316 EX xvld $xr3, \base, (3 * LASX_REG_WIDTH) 317 EX xvld $xr4, \base, (4 * LASX_REG_WIDTH) 318 EX xvld $xr5, \base, (5 * LASX_REG_WIDTH) 319 EX xvld $xr6, \base, (6 * LASX_REG_WIDTH) 320 EX xvld $xr7, \base, (7 * LASX_REG_WIDTH) 321 EX xvld $xr8, \base, (8 * LASX_REG_WIDTH) 322 EX xvld $xr9, \base, (9 * LASX_REG_WIDTH) 323 EX xvld $xr10, \base, (10 * LASX_REG_WIDTH) 324 EX xvld $xr11, \base, (11 * LASX_REG_WIDTH) 325 EX xvld $xr12, \base, (12 * LASX_REG_WIDTH) 326 EX xvld $xr13, \base, (13 * LASX_REG_WIDTH) 327 EX xvld $xr14, \base, (14 * LASX_REG_WIDTH) 328 EX xvld $xr15, \base, (15 * LASX_REG_WIDTH) 329 EX xvld $xr16, \base, (16 * LASX_REG_WIDTH) 330 EX xvld $xr17, \base, (17 * LASX_REG_WIDTH) 331 EX xvld $xr18, \base, (18 * LASX_REG_WIDTH) 332 EX xvld $xr19, \base, (19 * LASX_REG_WIDTH) 333 EX xvld $xr20, \base, (20 * LASX_REG_WIDTH) 334 EX xvld $xr21, \base, (21 * LASX_REG_WIDTH) 335 EX xvld $xr22, \base, (22 * LASX_REG_WIDTH) 336 EX xvld $xr23, \base, (23 * LASX_REG_WIDTH) 337 EX xvld $xr24, \base, (24 * LASX_REG_WIDTH) 338 EX xvld $xr25, \base, (25 * LASX_REG_WIDTH) 339 EX xvld $xr26, \base, (26 * LASX_REG_WIDTH) 340 EX xvld $xr27, \base, (27 * LASX_REG_WIDTH) 341 EX xvld $xr28, \base, (28 * LASX_REG_WIDTH) 342 EX xvld $xr29, \base, (29 * LASX_REG_WIDTH) 343 EX xvld $xr30, \base, (30 * LASX_REG_WIDTH) 344 EX xvld $xr31, \base, (31 * LASX_REG_WIDTH) 345#endif 346 .endm 347 348/* 349 * Save a thread's fp context. 350 */ 351SYM_FUNC_START(_save_fp) 352 fpu_save_csr a0 t1 353 fpu_save_double a0 t1 # clobbers t1 354 fpu_save_cc a0 t1 t2 # clobbers t1, t2 355 jr ra 356SYM_FUNC_END(_save_fp) 357EXPORT_SYMBOL(_save_fp) 358 359/* 360 * Restore a thread's fp context. 361 */ 362SYM_FUNC_START(_restore_fp) 363 fpu_restore_double a0 t1 # clobbers t1 364 fpu_restore_csr a0 t1 t2 365 fpu_restore_cc a0 t1 t2 # clobbers t1, t2 366 jr ra 367SYM_FUNC_END(_restore_fp) 368 369#ifdef CONFIG_CPU_HAS_LSX 370 371/* 372 * Save a thread's LSX vector context. 373 */ 374SYM_FUNC_START(_save_lsx) 375 lsx_save_all a0 t1 t2 376 jr ra 377SYM_FUNC_END(_save_lsx) 378EXPORT_SYMBOL(_save_lsx) 379 380/* 381 * Restore a thread's LSX vector context. 382 */ 383SYM_FUNC_START(_restore_lsx) 384 lsx_restore_all a0 t1 t2 385 jr ra 386SYM_FUNC_END(_restore_lsx) 387 388SYM_FUNC_START(_save_lsx_upper) 389 lsx_save_all_upper a0 t0 t1 390 jr ra 391SYM_FUNC_END(_save_lsx_upper) 392 393SYM_FUNC_START(_restore_lsx_upper) 394 lsx_restore_all_upper a0 t0 t1 395 jr ra 396SYM_FUNC_END(_restore_lsx_upper) 397EXPORT_SYMBOL(_restore_lsx_upper) 398 399SYM_FUNC_START(_init_lsx_upper) 400 lsx_init_all_upper t1 401 jr ra 402SYM_FUNC_END(_init_lsx_upper) 403#endif 404 405#ifdef CONFIG_CPU_HAS_LASX 406 407/* 408 * Save a thread's LASX vector context. 409 */ 410SYM_FUNC_START(_save_lasx) 411 lasx_save_all a0 t1 t2 412 jr ra 413SYM_FUNC_END(_save_lasx) 414EXPORT_SYMBOL(_save_lasx) 415 416/* 417 * Restore a thread's LASX vector context. 418 */ 419SYM_FUNC_START(_restore_lasx) 420 lasx_restore_all a0 t1 t2 421 jr ra 422SYM_FUNC_END(_restore_lasx) 423 424SYM_FUNC_START(_save_lasx_upper) 425 lasx_save_all_upper a0 t0 t1 426 jr ra 427SYM_FUNC_END(_save_lasx_upper) 428 429SYM_FUNC_START(_restore_lasx_upper) 430 lasx_restore_all_upper a0 t0 t1 431 jr ra 432SYM_FUNC_END(_restore_lasx_upper) 433EXPORT_SYMBOL(_restore_lasx_upper) 434 435SYM_FUNC_START(_init_lasx_upper) 436 lasx_init_all_upper t1 437 jr ra 438SYM_FUNC_END(_init_lasx_upper) 439#endif 440 441/* 442 * Load the FPU with signalling NANS. This bit pattern we're using has 443 * the property that no matter whether considered as single or as double 444 * precision represents signaling NANS. 445 * 446 * The value to initialize fcsr0 to comes in $a0. 447 */ 448 449SYM_FUNC_START(_init_fpu) 450 li.w t1, CSR_EUEN_FPEN 451 csrxchg t1, t1, LOONGARCH_CSR_EUEN 452 453 movgr2fcsr fcsr0, a0 454 455 li.w t1, -1 # SNaN 456 457#ifdef CONFIG_32BIT 458 movgr2fr.w $f0, t1 459 movgr2frh.w $f0, t1 460 movgr2fr.w $f1, t1 461 movgr2frh.w $f1, t1 462 movgr2fr.w $f2, t1 463 movgr2frh.w $f2, t1 464 movgr2fr.w $f3, t1 465 movgr2frh.w $f3, t1 466 movgr2fr.w $f4, t1 467 movgr2frh.w $f4, t1 468 movgr2fr.w $f5, t1 469 movgr2frh.w $f5, t1 470 movgr2fr.w $f6, t1 471 movgr2frh.w $f6, t1 472 movgr2fr.w $f7, t1 473 movgr2frh.w $f7, t1 474 movgr2fr.w $f8, t1 475 movgr2frh.w $f8, t1 476 movgr2fr.w $f9, t1 477 movgr2frh.w $f9, t1 478 movgr2fr.w $f10, t1 479 movgr2frh.w $f10, t1 480 movgr2fr.w $f11, t1 481 movgr2frh.w $f11, t1 482 movgr2fr.w $f12, t1 483 movgr2frh.w $f12, t1 484 movgr2fr.w $f13, t1 485 movgr2frh.w $f13, t1 486 movgr2fr.w $f14, t1 487 movgr2frh.w $f14, t1 488 movgr2fr.w $f15, t1 489 movgr2frh.w $f15, t1 490 movgr2fr.w $f16, t1 491 movgr2frh.w $f16, t1 492 movgr2fr.w $f17, t1 493 movgr2frh.w $f17, t1 494 movgr2fr.w $f18, t1 495 movgr2frh.w $f18, t1 496 movgr2fr.w $f19, t1 497 movgr2frh.w $f19, t1 498 movgr2fr.w $f20, t1 499 movgr2frh.w $f20, t1 500 movgr2fr.w $f21, t1 501 movgr2frh.w $f21, t1 502 movgr2fr.w $f22, t1 503 movgr2frh.w $f22, t1 504 movgr2fr.w $f23, t1 505 movgr2frh.w $f23, t1 506 movgr2fr.w $f24, t1 507 movgr2frh.w $f24, t1 508 movgr2fr.w $f25, t1 509 movgr2frh.w $f25, t1 510 movgr2fr.w $f26, t1 511 movgr2frh.w $f26, t1 512 movgr2fr.w $f27, t1 513 movgr2frh.w $f27, t1 514 movgr2fr.w $f28, t1 515 movgr2frh.w $f28, t1 516 movgr2fr.w $f29, t1 517 movgr2frh.w $f29, t1 518 movgr2fr.w $f30, t1 519 movgr2frh.w $f30, t1 520 movgr2fr.w $f31, t1 521 movgr2frh.w $f31, t1 522#else 523 movgr2fr.d $f0, t1 524 movgr2fr.d $f1, t1 525 movgr2fr.d $f2, t1 526 movgr2fr.d $f3, t1 527 movgr2fr.d $f4, t1 528 movgr2fr.d $f5, t1 529 movgr2fr.d $f6, t1 530 movgr2fr.d $f7, t1 531 movgr2fr.d $f8, t1 532 movgr2fr.d $f9, t1 533 movgr2fr.d $f10, t1 534 movgr2fr.d $f11, t1 535 movgr2fr.d $f12, t1 536 movgr2fr.d $f13, t1 537 movgr2fr.d $f14, t1 538 movgr2fr.d $f15, t1 539 movgr2fr.d $f16, t1 540 movgr2fr.d $f17, t1 541 movgr2fr.d $f18, t1 542 movgr2fr.d $f19, t1 543 movgr2fr.d $f20, t1 544 movgr2fr.d $f21, t1 545 movgr2fr.d $f22, t1 546 movgr2fr.d $f23, t1 547 movgr2fr.d $f24, t1 548 movgr2fr.d $f25, t1 549 movgr2fr.d $f26, t1 550 movgr2fr.d $f27, t1 551 movgr2fr.d $f28, t1 552 movgr2fr.d $f29, t1 553 movgr2fr.d $f30, t1 554 movgr2fr.d $f31, t1 555#endif 556 557 jr ra 558SYM_FUNC_END(_init_fpu) 559 560/* 561 * a0: fpregs 562 * a1: fcc 563 * a2: fcsr 564 */ 565SYM_FUNC_START(_save_fp_context) 566 sc_save_fcc a1 t1 t2 567 sc_save_fcsr a2 t1 568 sc_save_fp a0 569 li.w a0, 0 # success 570 jr ra 571SYM_FUNC_END(_save_fp_context) 572EXPORT_SYMBOL_GPL(_save_fp_context) 573 574/* 575 * a0: fpregs 576 * a1: fcc 577 * a2: fcsr 578 */ 579SYM_FUNC_START(_restore_fp_context) 580 sc_restore_fp a0 581 sc_restore_fcc a1 t1 t2 582 sc_restore_fcsr a2 t1 583 li.w a0, 0 # success 584 jr ra 585SYM_FUNC_END(_restore_fp_context) 586EXPORT_SYMBOL_GPL(_restore_fp_context) 587 588/* 589 * a0: fpregs 590 * a1: fcc 591 * a2: fcsr 592 */ 593SYM_FUNC_START(_save_lsx_context) 594 sc_save_fcc a1, t0, t1 595 sc_save_fcsr a2, t0 596 sc_save_lsx a0 597 li.w a0, 0 # success 598 jr ra 599SYM_FUNC_END(_save_lsx_context) 600EXPORT_SYMBOL_GPL(_save_lsx_context) 601 602/* 603 * a0: fpregs 604 * a1: fcc 605 * a2: fcsr 606 */ 607SYM_FUNC_START(_restore_lsx_context) 608 sc_restore_lsx a0 609 sc_restore_fcc a1, t1, t2 610 sc_restore_fcsr a2, t1 611 li.w a0, 0 # success 612 jr ra 613SYM_FUNC_END(_restore_lsx_context) 614EXPORT_SYMBOL_GPL(_restore_lsx_context) 615 616/* 617 * a0: fpregs 618 * a1: fcc 619 * a2: fcsr 620 */ 621SYM_FUNC_START(_save_lasx_context) 622 sc_save_fcc a1, t0, t1 623 sc_save_fcsr a2, t0 624 sc_save_lasx a0 625 li.w a0, 0 # success 626 jr ra 627SYM_FUNC_END(_save_lasx_context) 628EXPORT_SYMBOL_GPL(_save_lasx_context) 629 630/* 631 * a0: fpregs 632 * a1: fcc 633 * a2: fcsr 634 */ 635SYM_FUNC_START(_restore_lasx_context) 636 sc_restore_lasx a0 637 sc_restore_fcc a1, t1, t2 638 sc_restore_fcsr a2, t1 639 li.w a0, 0 # success 640 jr ra 641SYM_FUNC_END(_restore_lasx_context) 642EXPORT_SYMBOL_GPL(_restore_lasx_context) 643 644.L_fpu_fault: 645 li.w a0, -EFAULT # failure 646 jr ra 647 648#ifdef CONFIG_CPU_HAS_LBT 649STACK_FRAME_NON_STANDARD _restore_fp 650#ifdef CONFIG_CPU_HAS_LSX 651STACK_FRAME_NON_STANDARD _restore_lsx 652#endif 653#ifdef CONFIG_CPU_HAS_LASX 654STACK_FRAME_NON_STANDARD _restore_lasx 655#endif 656#endif 657