1/* $OpenBSD: lcore_float.S,v 1.23 2019/01/14 15:02:57 visa Exp $ */ 2 3/* 4 * Copyright (c) 2001-2003 Opsycon AB (www.opsycon.se / www.opsycon.com) 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 */ 28#include <sys/errno.h> 29#include <sys/syscall.h> 30 31#include <machine/param.h> 32#include <machine/asm.h> 33#include <machine/cpu.h> 34#include <mips64/mips_cpu.h> 35#include <machine/regnum.h> 36#include <machine/cpustate.h> 37 38#include "assym.h" 39 40 .set mips3 41 .set noreorder # Noreorder is default style! 42 .set hardfloat 43 44/*---------------------------------------------------------------------------- 45 * 46 * MipsSwitchFPState -- 47 * 48 * Save the current state into 'from' and restore it from 'to'. 49 * 50 * MipsSwitchFPState(from, to) 51 * struct proc *from; 52 * struct user *to; 53 * 54 * Results: 55 * None. 56 * 57 * Side effects: 58 * None. 59 * 60 *---------------------------------------------------------------------------- 61 */ 62LEAF(MipsSwitchFPState, 0) 63 MFC0 t1, COP_0_STATUS_REG # Save old SR 64 MFC0_HAZARD 65 or t0, t1, SR_COP_1_BIT|SR_FR_32 # enable the coprocessor 66 MTC0 t0, COP_0_STATUS_REG 67 MTC0_SR_CU_HAZARD 68 69 beq a0, zero, 1f # skip save if NULL pointer 70 NOP 71/* 72 * First read out the status register to make sure that all FP operations 73 * have completed. 74 */ 75 PTR_L a0, P_ADDR(a0) # get pointer to pcb for proc 76 cfc1 t0, FPC_CSR # stall til FP done 77 cfc1 t0, FPC_CSR # now get status 78 LI t3, ~SR_COP_1_BIT 79 REG_L t2, PCB_REGS+(SR * REGSZ)(a0) # get CPU status register 80 REG_S t0, PCB_FPREGS+(32 * REGSZ)(a0) # save FP status 81 and t2, t2, t3 # clear COP_1 enable bit 82 REG_S t2, PCB_REGS+(SR * REGSZ)(a0) # save new status register 83/* 84 * Save the floating point registers. 85 */ 86 sdc1 $f0, PCB_FPREGS+(0 * REGSZ)(a0) 87 sdc1 $f1, PCB_FPREGS+(1 * REGSZ)(a0) 88 sdc1 $f2, PCB_FPREGS+(2 * REGSZ)(a0) 89 sdc1 $f3, PCB_FPREGS+(3 * REGSZ)(a0) 90 sdc1 $f4, PCB_FPREGS+(4 * REGSZ)(a0) 91 sdc1 $f5, PCB_FPREGS+(5 * REGSZ)(a0) 92 sdc1 $f6, PCB_FPREGS+(6 * REGSZ)(a0) 93 sdc1 $f7, PCB_FPREGS+(7 * REGSZ)(a0) 94 sdc1 $f8, PCB_FPREGS+(8 * REGSZ)(a0) 95 sdc1 $f9, PCB_FPREGS+(9 * REGSZ)(a0) 96 sdc1 $f10, PCB_FPREGS+(10 * REGSZ)(a0) 97 sdc1 $f11, PCB_FPREGS+(11 * REGSZ)(a0) 98 sdc1 $f12, PCB_FPREGS+(12 * REGSZ)(a0) 99 sdc1 $f13, PCB_FPREGS+(13 * REGSZ)(a0) 100 sdc1 $f14, PCB_FPREGS+(14 * REGSZ)(a0) 101 sdc1 $f15, PCB_FPREGS+(15 * REGSZ)(a0) 102 sdc1 $f16, PCB_FPREGS+(16 * REGSZ)(a0) 103 sdc1 $f17, PCB_FPREGS+(17 * REGSZ)(a0) 104 sdc1 $f18, PCB_FPREGS+(18 * REGSZ)(a0) 105 sdc1 $f19, PCB_FPREGS+(19 * REGSZ)(a0) 106 sdc1 $f20, PCB_FPREGS+(20 * REGSZ)(a0) 107 sdc1 $f21, PCB_FPREGS+(21 * REGSZ)(a0) 108 sdc1 $f22, PCB_FPREGS+(22 * REGSZ)(a0) 109 sdc1 $f23, PCB_FPREGS+(23 * REGSZ)(a0) 110 sdc1 $f24, PCB_FPREGS+(24 * REGSZ)(a0) 111 sdc1 $f25, PCB_FPREGS+(25 * REGSZ)(a0) 112 sdc1 $f26, PCB_FPREGS+(26 * REGSZ)(a0) 113 sdc1 $f27, PCB_FPREGS+(27 * REGSZ)(a0) 114 sdc1 $f28, PCB_FPREGS+(28 * REGSZ)(a0) 115 sdc1 $f29, PCB_FPREGS+(29 * REGSZ)(a0) 116 sdc1 $f30, PCB_FPREGS+(30 * REGSZ)(a0) 117 sdc1 $f31, PCB_FPREGS+(31 * REGSZ)(a0) 118 1191: 120/* 121 * Restore the floating point registers. 122 */ 123 REG_L t0, PCB_FPREGS+(32 * REGSZ)(a1) # get status register 124 ldc1 $f0, PCB_FPREGS+(0 * REGSZ)(a1) 125 ldc1 $f1, PCB_FPREGS+(1 * REGSZ)(a1) 126 ldc1 $f2, PCB_FPREGS+(2 * REGSZ)(a1) 127 ldc1 $f3, PCB_FPREGS+(3 * REGSZ)(a1) 128 ldc1 $f4, PCB_FPREGS+(4 * REGSZ)(a1) 129 ldc1 $f5, PCB_FPREGS+(5 * REGSZ)(a1) 130 ldc1 $f6, PCB_FPREGS+(6 * REGSZ)(a1) 131 ldc1 $f7, PCB_FPREGS+(7 * REGSZ)(a1) 132 ldc1 $f8, PCB_FPREGS+(8 * REGSZ)(a1) 133 ldc1 $f9, PCB_FPREGS+(9 * REGSZ)(a1) 134 ldc1 $f10, PCB_FPREGS+(10 * REGSZ)(a1) 135 ldc1 $f11, PCB_FPREGS+(11 * REGSZ)(a1) 136 ldc1 $f12, PCB_FPREGS+(12 * REGSZ)(a1) 137 ldc1 $f13, PCB_FPREGS+(13 * REGSZ)(a1) 138 ldc1 $f14, PCB_FPREGS+(14 * REGSZ)(a1) 139 ldc1 $f15, PCB_FPREGS+(15 * REGSZ)(a1) 140 ldc1 $f16, PCB_FPREGS+(16 * REGSZ)(a1) 141 ldc1 $f17, PCB_FPREGS+(17 * REGSZ)(a1) 142 ldc1 $f18, PCB_FPREGS+(18 * REGSZ)(a1) 143 ldc1 $f19, PCB_FPREGS+(19 * REGSZ)(a1) 144 ldc1 $f20, PCB_FPREGS+(20 * REGSZ)(a1) 145 ldc1 $f21, PCB_FPREGS+(21 * REGSZ)(a1) 146 ldc1 $f22, PCB_FPREGS+(22 * REGSZ)(a1) 147 ldc1 $f23, PCB_FPREGS+(23 * REGSZ)(a1) 148 ldc1 $f24, PCB_FPREGS+(24 * REGSZ)(a1) 149 ldc1 $f25, PCB_FPREGS+(25 * REGSZ)(a1) 150 ldc1 $f26, PCB_FPREGS+(26 * REGSZ)(a1) 151 ldc1 $f27, PCB_FPREGS+(27 * REGSZ)(a1) 152 ldc1 $f28, PCB_FPREGS+(28 * REGSZ)(a1) 153 ldc1 $f29, PCB_FPREGS+(29 * REGSZ)(a1) 154 ldc1 $f30, PCB_FPREGS+(30 * REGSZ)(a1) 155 ldc1 $f31, PCB_FPREGS+(31 * REGSZ)(a1) 156 157 ctc1 t0, FPC_CSR 158 NOP 159 160 MTC0 t1, COP_0_STATUS_REG # Restore the status register. 161 MTC0_SR_CU_HAZARD 162 j ra 163 NOP 164END(MipsSwitchFPState) 165 166LEAF(MipsSwitchFPState16, 0) 167 MFC0 t1, COP_0_STATUS_REG # Save old SR 168 MFC0_HAZARD 169 or t0, t1, SR_COP_1_BIT # enable the coprocessor 170 MTC0 t0, COP_0_STATUS_REG 171 MTC0_SR_CU_HAZARD 172 173 beq a0, zero, 1f # skip save if NULL pointer 174 NOP 175/* 176 * First read out the status register to make sure that all FP operations 177 * have completed. 178 */ 179 PTR_L a0, P_ADDR(a0) # get pointer to pcb for proc 180 cfc1 t0, FPC_CSR # stall til FP done 181 cfc1 t0, FPC_CSR # now get status 182 LI t3, ~SR_COP_1_BIT 183 REG_L t2, PCB_REGS+(SR * REGSZ)(a0) # get CPU status register 184 REG_S t0, PCB_FPREGS+(32 * REGSZ)(a0) # save FP status 185 and t2, t2, t3 # clear COP_1 enable bit 186 REG_S t2, PCB_REGS+(SR * REGSZ)(a0) # save new status register 187/* 188 * Save the floating point registers. 189 */ 190 swc1 $f0, PCB_FPREGS+(0 * REGSZ)(a0) 191 swc1 $f1, PCB_FPREGS+(1 * REGSZ)(a0) 192 swc1 $f2, PCB_FPREGS+(2 * REGSZ)(a0) 193 swc1 $f3, PCB_FPREGS+(3 * REGSZ)(a0) 194 swc1 $f4, PCB_FPREGS+(4 * REGSZ)(a0) 195 swc1 $f5, PCB_FPREGS+(5 * REGSZ)(a0) 196 swc1 $f6, PCB_FPREGS+(6 * REGSZ)(a0) 197 swc1 $f7, PCB_FPREGS+(7 * REGSZ)(a0) 198 swc1 $f8, PCB_FPREGS+(8 * REGSZ)(a0) 199 swc1 $f9, PCB_FPREGS+(9 * REGSZ)(a0) 200 swc1 $f10, PCB_FPREGS+(10 * REGSZ)(a0) 201 swc1 $f11, PCB_FPREGS+(11 * REGSZ)(a0) 202 swc1 $f12, PCB_FPREGS+(12 * REGSZ)(a0) 203 swc1 $f13, PCB_FPREGS+(13 * REGSZ)(a0) 204 swc1 $f14, PCB_FPREGS+(14 * REGSZ)(a0) 205 swc1 $f15, PCB_FPREGS+(15 * REGSZ)(a0) 206 swc1 $f16, PCB_FPREGS+(16 * REGSZ)(a0) 207 swc1 $f17, PCB_FPREGS+(17 * REGSZ)(a0) 208 swc1 $f18, PCB_FPREGS+(18 * REGSZ)(a0) 209 swc1 $f19, PCB_FPREGS+(19 * REGSZ)(a0) 210 swc1 $f20, PCB_FPREGS+(20 * REGSZ)(a0) 211 swc1 $f21, PCB_FPREGS+(21 * REGSZ)(a0) 212 swc1 $f22, PCB_FPREGS+(22 * REGSZ)(a0) 213 swc1 $f23, PCB_FPREGS+(23 * REGSZ)(a0) 214 swc1 $f24, PCB_FPREGS+(24 * REGSZ)(a0) 215 swc1 $f25, PCB_FPREGS+(25 * REGSZ)(a0) 216 swc1 $f26, PCB_FPREGS+(26 * REGSZ)(a0) 217 swc1 $f27, PCB_FPREGS+(27 * REGSZ)(a0) 218 swc1 $f28, PCB_FPREGS+(28 * REGSZ)(a0) 219 swc1 $f29, PCB_FPREGS+(29 * REGSZ)(a0) 220 swc1 $f30, PCB_FPREGS+(30 * REGSZ)(a0) 221 swc1 $f31, PCB_FPREGS+(31 * REGSZ)(a0) 222 2231: 224/* 225 * Restore the floating point registers. 226 */ 227 REG_L t0, PCB_FPREGS+(32 * REGSZ)(a1) # get status register 228 lwc1 $f0, PCB_FPREGS+(0 * REGSZ)(a1) 229 lwc1 $f1, PCB_FPREGS+(1 * REGSZ)(a1) 230 lwc1 $f2, PCB_FPREGS+(2 * REGSZ)(a1) 231 lwc1 $f3, PCB_FPREGS+(3 * REGSZ)(a1) 232 lwc1 $f4, PCB_FPREGS+(4 * REGSZ)(a1) 233 lwc1 $f5, PCB_FPREGS+(5 * REGSZ)(a1) 234 lwc1 $f6, PCB_FPREGS+(6 * REGSZ)(a1) 235 lwc1 $f7, PCB_FPREGS+(7 * REGSZ)(a1) 236 lwc1 $f8, PCB_FPREGS+(8 * REGSZ)(a1) 237 lwc1 $f9, PCB_FPREGS+(9 * REGSZ)(a1) 238 lwc1 $f10, PCB_FPREGS+(10 * REGSZ)(a1) 239 lwc1 $f11, PCB_FPREGS+(11 * REGSZ)(a1) 240 lwc1 $f12, PCB_FPREGS+(12 * REGSZ)(a1) 241 lwc1 $f13, PCB_FPREGS+(13 * REGSZ)(a1) 242 lwc1 $f14, PCB_FPREGS+(14 * REGSZ)(a1) 243 lwc1 $f15, PCB_FPREGS+(15 * REGSZ)(a1) 244 lwc1 $f16, PCB_FPREGS+(16 * REGSZ)(a1) 245 lwc1 $f17, PCB_FPREGS+(17 * REGSZ)(a1) 246 lwc1 $f18, PCB_FPREGS+(18 * REGSZ)(a1) 247 lwc1 $f19, PCB_FPREGS+(19 * REGSZ)(a1) 248 lwc1 $f20, PCB_FPREGS+(20 * REGSZ)(a1) 249 lwc1 $f21, PCB_FPREGS+(21 * REGSZ)(a1) 250 lwc1 $f22, PCB_FPREGS+(22 * REGSZ)(a1) 251 lwc1 $f23, PCB_FPREGS+(23 * REGSZ)(a1) 252 lwc1 $f24, PCB_FPREGS+(24 * REGSZ)(a1) 253 lwc1 $f25, PCB_FPREGS+(25 * REGSZ)(a1) 254 lwc1 $f26, PCB_FPREGS+(26 * REGSZ)(a1) 255 lwc1 $f27, PCB_FPREGS+(27 * REGSZ)(a1) 256 lwc1 $f28, PCB_FPREGS+(28 * REGSZ)(a1) 257 lwc1 $f29, PCB_FPREGS+(29 * REGSZ)(a1) 258 lwc1 $f30, PCB_FPREGS+(30 * REGSZ)(a1) 259 lwc1 $f31, PCB_FPREGS+(31 * REGSZ)(a1) 260 261 ctc1 t0, FPC_CSR 262 NOP 263 264 MTC0 t1, COP_0_STATUS_REG # Restore the status register. 265 MTC0_SR_CU_HAZARD 266 j ra 267 NOP 268END(MipsSwitchFPState16) 269 270/*---------------------------------------------------------------------------- 271 * 272 * MipsSaveCurFPState -- 273 * 274 * Save the current floating point coprocessor state. 275 * 276 * MipsSaveCurFPState(p) 277 * struct proc *p; 278 * 279 * Results: 280 * None. 281 * 282 * Side effects: 283 * curcpu()->ci_fpuproc is cleared. 284 * 285 *---------------------------------------------------------------------------- 286 */ 287LEAF(MipsSaveCurFPState, 0) 288 PTR_L a0, P_ADDR(a0) # get pointer to pcb for proc 289 MFC0 t1, COP_0_STATUS_REG # Disable interrupts and 290 MFC0_HAZARD 291 or t0, t1, SR_COP_1_BIT|SR_FR_32 # enable the coprocessor 292 MTC0 t0, COP_0_STATUS_REG 293 MTC0_SR_IE_HAZARD 294 GET_CPU_INFO(t2, t3) 295 PTR_S zero, CI_FPUPROC(t2) # indicate state has been saved 296/* 297 * First read out the status register to make sure that all FP operations 298 * have completed. 299 */ 300 REG_L t2, PCB_REGS+(SR * REGSZ)(a0) # get CPU status register 301 LI t3, ~SR_COP_1_BIT 302 and t2, t2, t3 # clear COP_1 enable bit 303 cfc1 t0, FPC_CSR # stall til FP done 304 cfc1 t0, FPC_CSR # now get status 305 REG_S t2, PCB_REGS+(SR * REGSZ)(a0) # save new status register 306 REG_S t0, PCB_FPREGS+(32 * REGSZ)(a0) # save FP status 307/* 308 * Save the floating point registers. 309 */ 310 sdc1 $f0, PCB_FPREGS+(0 * REGSZ)(a0) 311 sdc1 $f1, PCB_FPREGS+(1 * REGSZ)(a0) 312 sdc1 $f2, PCB_FPREGS+(2 * REGSZ)(a0) 313 sdc1 $f3, PCB_FPREGS+(3 * REGSZ)(a0) 314 sdc1 $f4, PCB_FPREGS+(4 * REGSZ)(a0) 315 sdc1 $f5, PCB_FPREGS+(5 * REGSZ)(a0) 316 sdc1 $f6, PCB_FPREGS+(6 * REGSZ)(a0) 317 sdc1 $f7, PCB_FPREGS+(7 * REGSZ)(a0) 318 sdc1 $f8, PCB_FPREGS+(8 * REGSZ)(a0) 319 sdc1 $f9, PCB_FPREGS+(9 * REGSZ)(a0) 320 sdc1 $f10, PCB_FPREGS+(10 * REGSZ)(a0) 321 sdc1 $f11, PCB_FPREGS+(11 * REGSZ)(a0) 322 sdc1 $f12, PCB_FPREGS+(12 * REGSZ)(a0) 323 sdc1 $f13, PCB_FPREGS+(13 * REGSZ)(a0) 324 sdc1 $f14, PCB_FPREGS+(14 * REGSZ)(a0) 325 sdc1 $f15, PCB_FPREGS+(15 * REGSZ)(a0) 326 sdc1 $f16, PCB_FPREGS+(16 * REGSZ)(a0) 327 sdc1 $f17, PCB_FPREGS+(17 * REGSZ)(a0) 328 sdc1 $f18, PCB_FPREGS+(18 * REGSZ)(a0) 329 sdc1 $f19, PCB_FPREGS+(19 * REGSZ)(a0) 330 sdc1 $f20, PCB_FPREGS+(20 * REGSZ)(a0) 331 sdc1 $f21, PCB_FPREGS+(21 * REGSZ)(a0) 332 sdc1 $f22, PCB_FPREGS+(22 * REGSZ)(a0) 333 sdc1 $f23, PCB_FPREGS+(23 * REGSZ)(a0) 334 sdc1 $f24, PCB_FPREGS+(24 * REGSZ)(a0) 335 sdc1 $f25, PCB_FPREGS+(25 * REGSZ)(a0) 336 sdc1 $f26, PCB_FPREGS+(26 * REGSZ)(a0) 337 sdc1 $f27, PCB_FPREGS+(27 * REGSZ)(a0) 338 sdc1 $f28, PCB_FPREGS+(28 * REGSZ)(a0) 339 sdc1 $f29, PCB_FPREGS+(29 * REGSZ)(a0) 340 sdc1 $f30, PCB_FPREGS+(30 * REGSZ)(a0) 341 sdc1 $f31, PCB_FPREGS+(31 * REGSZ)(a0) 342 343 MTC0 t1, COP_0_STATUS_REG # Restore the status register. 344 MTC0_SR_IE_HAZARD 345 j ra 346 NOP 347END(MipsSaveCurFPState) 348 349LEAF(MipsSaveCurFPState16, 0) 350 PTR_L a0, P_ADDR(a0) # get pointer to pcb for proc 351 MFC0 t1, COP_0_STATUS_REG # Disable interrupts and 352 MFC0_HAZARD 353 or t0, t1, SR_COP_1_BIT # enable the coprocessor 354 MTC0 t0, COP_0_STATUS_REG 355 MTC0_SR_IE_HAZARD 356 GET_CPU_INFO(t2, t3) 357 PTR_S zero, CI_FPUPROC(t2) # indicate state has been saved 358/* 359 * First read out the status register to make sure that all FP operations 360 * have completed. 361 */ 362 REG_L t2, PCB_REGS+(SR * REGSZ)(a0) # get CPU status register 363 LI t3, ~SR_COP_1_BIT 364 and t2, t2, t3 # clear COP_1 enable bit 365 cfc1 t0, FPC_CSR # stall til FP done 366 cfc1 t0, FPC_CSR # now get status 367 REG_S t2, PCB_REGS+(SR * REGSZ)(a0) # save new status register 368 REG_S t0, PCB_FPREGS+(32 * REGSZ)(a0) # save FP status 369/* 370 * Save the floating point registers. 371 */ 372 swc1 $f0, PCB_FPREGS+(0 * REGSZ)(a0) 373 swc1 $f1, PCB_FPREGS+(1 * REGSZ)(a0) 374 swc1 $f2, PCB_FPREGS+(2 * REGSZ)(a0) 375 swc1 $f3, PCB_FPREGS+(3 * REGSZ)(a0) 376 swc1 $f4, PCB_FPREGS+(4 * REGSZ)(a0) 377 swc1 $f5, PCB_FPREGS+(5 * REGSZ)(a0) 378 swc1 $f6, PCB_FPREGS+(6 * REGSZ)(a0) 379 swc1 $f7, PCB_FPREGS+(7 * REGSZ)(a0) 380 swc1 $f8, PCB_FPREGS+(8 * REGSZ)(a0) 381 swc1 $f9, PCB_FPREGS+(9 * REGSZ)(a0) 382 swc1 $f10, PCB_FPREGS+(10 * REGSZ)(a0) 383 swc1 $f11, PCB_FPREGS+(11 * REGSZ)(a0) 384 swc1 $f12, PCB_FPREGS+(12 * REGSZ)(a0) 385 swc1 $f13, PCB_FPREGS+(13 * REGSZ)(a0) 386 swc1 $f14, PCB_FPREGS+(14 * REGSZ)(a0) 387 swc1 $f15, PCB_FPREGS+(15 * REGSZ)(a0) 388 swc1 $f16, PCB_FPREGS+(16 * REGSZ)(a0) 389 swc1 $f17, PCB_FPREGS+(17 * REGSZ)(a0) 390 swc1 $f18, PCB_FPREGS+(18 * REGSZ)(a0) 391 swc1 $f19, PCB_FPREGS+(19 * REGSZ)(a0) 392 swc1 $f20, PCB_FPREGS+(20 * REGSZ)(a0) 393 swc1 $f21, PCB_FPREGS+(21 * REGSZ)(a0) 394 swc1 $f22, PCB_FPREGS+(22 * REGSZ)(a0) 395 swc1 $f23, PCB_FPREGS+(23 * REGSZ)(a0) 396 swc1 $f24, PCB_FPREGS+(24 * REGSZ)(a0) 397 swc1 $f25, PCB_FPREGS+(25 * REGSZ)(a0) 398 swc1 $f26, PCB_FPREGS+(26 * REGSZ)(a0) 399 swc1 $f27, PCB_FPREGS+(27 * REGSZ)(a0) 400 swc1 $f28, PCB_FPREGS+(28 * REGSZ)(a0) 401 swc1 $f29, PCB_FPREGS+(29 * REGSZ)(a0) 402 swc1 $f30, PCB_FPREGS+(30 * REGSZ)(a0) 403 swc1 $f31, PCB_FPREGS+(31 * REGSZ)(a0) 404 405 MTC0 t1, COP_0_STATUS_REG # Restore the status register. 406 MTC0_SR_IE_HAZARD 407 j ra 408 NOP 409END(MipsSaveCurFPState16) 410 411/*---------------------------------------------------------------------------- 412 * 413 * cp1_get_prid 414 * 415 * Get the floating point co-processor id. 416 * 417 * cp1_get_prid(void) 418 * 419 * Results: 420 * FPC_ID 421 * 422 * Side effects: 423 * None. 424 * 425 *---------------------------------------------------------------------------- 426 */ 427LEAF(cp1_get_prid, 0) 428 MFC0 v1, COP_0_STATUS_REG 429 MFC0_HAZARD 430 li a0, SR_COP_1_BIT 431 or v1, a0 432 MTC0 v1, COP_0_STATUS_REG 433 MTC0_SR_CU_HAZARD 434 cfc1 v0, FPC_ID 435 xor v1, a0 436 MTC0 v1, COP_0_STATUS_REG 437 MTC0_SR_CU_HAZARD 438 jr ra 439 NOP 440END(cp1_get_prid) 441