|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* ! 26: * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 ! 27: * All Rights Reserved ! 28: * ! 29: * Permission to use, copy, modify, and distribute this software and ! 30: * its documentation for any purpose and without fee is hereby granted, ! 31: * provided that the above copyright notice appears in all copies and ! 32: * that both the copyright notice and this permission notice appear in ! 33: * supporting documentation. ! 34: * ! 35: * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE ! 36: * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ! 37: * FOR A PARTICULAR PURPOSE. ! 38: * ! 39: * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR ! 40: * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ! 41: * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, ! 42: * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION ! 43: * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ! 44: */ ! 45: /* ! 46: * MKLINUX-1.0DR2 ! 47: */ ! 48: ! 49: #include <cpus.h> ! 50: #include <assym.h> ! 51: #include <debug.h> ! 52: #include <ppc/asm.h> ! 53: #include <ppc/proc_reg.h> ! 54: #include <mach/ppc/vm_param.h> ! 55: ! 56: ! 57: .text ! 58: /* ! 59: * void fpu_save(void) ! 60: * ! 61: * Called when there's an exception or when get_state is called ! 62: * for the FPU state. Puts a copy of the current thread's state ! 63: * into the PCB pointed to by fpu_pcb, and leaves the FPU enabled. ! 64: * ! 65: * video_scroll.s assumes that ARG0-5 won't be trampled on, and ! 66: * that fpu_save doesn't need a frame, otherwise it would need ! 67: * a frame itself. Why not oblige! ! 68: * ! 69: * NOTE: This routine is meant for kernel Floating Point ! 70: * use. It is called to flush the current context to the correct ! 71: * pcb and leaves with MSR_FP on so the kernel can use the FPU. ! 72: * ! 73: * IT IS THE CALLERS RESPONSIBILITY TO TURN THE FPU OFF AFTER USE!!! ! 74: * ! 75: * The function fpu_disable is used to accomplish this from C language ! 76: * programs or is can be done at the end of an assembly routine. ! 77: */ ! 78: ! 79: ENTRY(fpu_save, TAG_NO_FRAME_USED) ! 80: /* ! 81: * Turn the FPU back on (should this be a separate routine?) ! 82: */ ! 83: mfmsr r0 ! 84: andi. r0, r0, MASK(MSR_FP) ! 85: bne .L_fpu_save_no_owner ! 86: ! 87: mfmsr r0 ! 88: ori r0, r0, MASK(MSR_FP) /* bit is in low-order 16 */ ! 89: mtmsr r0 ! 90: isync ! 91: ! 92: mfsprg ARG7, 0 /* HACK - need to get around r2 problem */ ! 93: ! 94: lwz ARG6, PP_FPU_PCB(ARG7) ! 95: ! 96: /* ! 97: * See if any thread owns the FPU. If not, we can skip the state save. ! 98: */ ! 99: cmpwi CR0, ARG6, 0 ! 100: beq- CR0, .L_fpu_save_no_owner ! 101: ! 102: /* ! 103: * Save the current FPU state into the PCB of the thread that owns it. ! 104: */ ! 105: stfd f0, PCB_FS_F0(ARG6) ! 106: stfd f1, PCB_FS_F1(ARG6) ! 107: stfd f2, PCB_FS_F2(ARG6) ! 108: stfd f3, PCB_FS_F3(ARG6) ! 109: stfd f4, PCB_FS_F4(ARG6) ! 110: stfd f5, PCB_FS_F5(ARG6) ! 111: stfd f6, PCB_FS_F6(ARG6) ! 112: stfd f7, PCB_FS_F7(ARG6) ! 113: mffs f0 /* fpscr in f0 low 32 bits*/ ! 114: stfd f8, PCB_FS_F8(ARG6) ! 115: stfd f9, PCB_FS_F9(ARG6) ! 116: stfd f10, PCB_FS_F10(ARG6) ! 117: stfd f11, PCB_FS_F11(ARG6) ! 118: stfd f12, PCB_FS_F12(ARG6) ! 119: stfd f13, PCB_FS_F13(ARG6) ! 120: stfd f14, PCB_FS_F14(ARG6) ! 121: stfd f15, PCB_FS_F15(ARG6) ! 122: stfd f0, PCB_FS_FPSCR(ARG6) /* Store junk 32 bits+fpscr */ ! 123: stfd f16, PCB_FS_F16(ARG6) ! 124: stfd f17, PCB_FS_F17(ARG6) ! 125: stfd f18, PCB_FS_F18(ARG6) ! 126: stfd f19, PCB_FS_F19(ARG6) ! 127: stfd f20, PCB_FS_F20(ARG6) ! 128: stfd f21, PCB_FS_F21(ARG6) ! 129: stfd f22, PCB_FS_F22(ARG6) ! 130: stfd f23, PCB_FS_F23(ARG6) ! 131: stfd f24, PCB_FS_F24(ARG6) ! 132: stfd f25, PCB_FS_F25(ARG6) ! 133: stfd f26, PCB_FS_F26(ARG6) ! 134: stfd f27, PCB_FS_F27(ARG6) ! 135: stfd f28, PCB_FS_F28(ARG6) ! 136: stfd f29, PCB_FS_F29(ARG6) ! 137: stfd f30, PCB_FS_F30(ARG6) ! 138: stfd f31, PCB_FS_F31(ARG6) ! 139: ! 140: /* Mark the FPU as having no owner now */ ! 141: li r0, 0 ! 142: stw r0, PP_FPU_PCB(ARG7) ! 143: ! 144: /* ! 145: * Turn off the FPU for the old owner ! 146: */ ! 147: lwz r0, SS_SRR1(ARG6) ! 148: rlwinm r0, r0, 0, MSR_FP_BIT+1, MSR_FP_BIT-1 ! 149: stw r0, SS_SRR1(ARG6) ! 150: ! 151: .L_fpu_save_no_owner: ! 152: blr ! 153: ! 154: ! 155: ENTRY(fpu_save_thread, TAG_NO_FRAME_USED) ! 156: ! 157: /* ! 158: * Turn the FPU back on (should this be a separate routine?) ! 159: */ ! 160: ! 161: mfmsr r0 ! 162: ori r0, r0, MASK(MSR_FP) /* bit is in low-order 16 */ ! 163: mtmsr r0 ! 164: isync ! 165: ! 166: mfsprg ARG7, 0 /* HACK - need to get around r2 problem */ ! 167: ! 168: lwz ARG6, PP_FPU_PCB(ARG7) ! 169: /* ! 170: * See if any thread owns the FPU. If not, we can skip the state save. ! 171: */ ! 172: cmpwi CR0, ARG6, 0 ! 173: beq- CR0, .L_fpu_save_thread_no_owner ! 174: ! 175: /* ! 176: * Save the current FPU state into the PCB of the thread that owns it. ! 177: */ ! 178: stfd f0, PCB_FS_F0(ARG6) ! 179: stfd f1, PCB_FS_F1(ARG6) ! 180: stfd f2, PCB_FS_F2(ARG6) ! 181: stfd f3, PCB_FS_F3(ARG6) ! 182: stfd f4, PCB_FS_F4(ARG6) ! 183: stfd f5, PCB_FS_F5(ARG6) ! 184: stfd f6, PCB_FS_F6(ARG6) ! 185: stfd f7, PCB_FS_F7(ARG6) ! 186: mffs f0 /* fpscr in f0 low 32 bits*/ ! 187: stfd f8, PCB_FS_F8(ARG6) ! 188: stfd f9, PCB_FS_F9(ARG6) ! 189: stfd f10, PCB_FS_F10(ARG6) ! 190: stfd f11, PCB_FS_F11(ARG6) ! 191: stfd f12, PCB_FS_F12(ARG6) ! 192: stfd f13, PCB_FS_F13(ARG6) ! 193: stfd f14, PCB_FS_F14(ARG6) ! 194: stfd f15, PCB_FS_F15(ARG6) ! 195: stfd f0, PCB_FS_FPSCR(ARG6) /* Store junk 32 bits+fpscr */ ! 196: stfd f16, PCB_FS_F16(ARG6) ! 197: stfd f17, PCB_FS_F17(ARG6) ! 198: stfd f18, PCB_FS_F18(ARG6) ! 199: stfd f19, PCB_FS_F19(ARG6) ! 200: stfd f20, PCB_FS_F20(ARG6) ! 201: stfd f21, PCB_FS_F21(ARG6) ! 202: stfd f22, PCB_FS_F22(ARG6) ! 203: stfd f23, PCB_FS_F23(ARG6) ! 204: stfd f24, PCB_FS_F24(ARG6) ! 205: stfd f25, PCB_FS_F25(ARG6) ! 206: stfd f26, PCB_FS_F26(ARG6) ! 207: stfd f27, PCB_FS_F27(ARG6) ! 208: stfd f28, PCB_FS_F28(ARG6) ! 209: stfd f29, PCB_FS_F29(ARG6) ! 210: stfd f30, PCB_FS_F30(ARG6) ! 211: stfd f31, PCB_FS_F31(ARG6) ! 212: ! 213: /* ! 214: * Turn off the FPU for the old owner ! 215: */ ! 216: lwz r0, SS_SRR1(ARG6) ! 217: rlwinm r0, r0, 0, MSR_FP_BIT+1, MSR_FP_BIT-1 ! 218: stw r0, SS_SRR1(ARG6) ! 219: ! 220: /* Store current PCB address in fpu_pcb to claim fpu for thread */ ! 221: lwz ARG6, PP_CPU_DATA(ARG7) ! 222: lwz ARG6, CPU_ACTIVE_THREAD(ARG6) ! 223: lwz ARG6, THREAD_PCB(ARG6) ! 224: stw ARG6, PP_FPU_PCB(ARG7) ! 225: ! 226: .L_fpu_save_thread_no_owner: ! 227: blr ! 228: ! 229: /* ! 230: * fpu_restore() ! 231: * ! 232: * restore the current user thread Floating-Point context in the FPU and ! 233: * set the FPU ownership to the current user thread. ! 234: * ! 235: * This code runs in virtual address mode with interrupts off. ! 236: * ! 237: */ ! 238: ! 239: .text ! 240: ENTRY(fpu_restore, TAG_NO_FRAME_USED) ! 241: ! 242: mfsprg r4, 0 /* load per_proc_info pointer */ ! 243: ! 244: /* See if the current thread owns the FPU, if so, just return */ ! 245: lwz r3, PP_FPU_PCB(r4) ! 246: ! 247: lwz r5, PP_CPU_DATA(r4) ! 248: lwz r5, CPU_ACTIVE_THREAD(r5) ! 249: lwz r5, THREAD_PCB(r5) ! 250: ! 251: cmpw cr0, r5, r3 ! 252: beq cr0, .L_fpu_restore_ret ! 253: ! 254: /* Store current PCB address in fpu_pcb to claim fpu for thread */ ! 255: stw r5, PP_FPU_PCB(r4) ! 256: ! 257: /* restore current user thread Floating-Point context */ ! 258: lfd f31, PCB_FS_FPSCR(r5) /* Load junk 32 bits+fpscr */ ! 259: lfd f0, PCB_FS_F0(r5) ! 260: lfd f1, PCB_FS_F1(r5) ! 261: lfd f2, PCB_FS_F2(r5) ! 262: lfd f3, PCB_FS_F3(r5) ! 263: lfd f4, PCB_FS_F4(r5) ! 264: lfd f5, PCB_FS_F5(r5) ! 265: lfd f6, PCB_FS_F6(r5) ! 266: lfd f7, PCB_FS_F7(r5) ! 267: mtfsf 0xff, f31 /* fpscr in f0 low 32 bits*/ ! 268: lfd f8, PCB_FS_F8(r5) ! 269: lfd f9, PCB_FS_F9(r5) ! 270: lfd f10, PCB_FS_F10(r5) ! 271: lfd f11, PCB_FS_F11(r5) ! 272: lfd f12, PCB_FS_F12(r5) ! 273: lfd f13, PCB_FS_F13(r5) ! 274: lfd f14, PCB_FS_F14(r5) ! 275: lfd f15, PCB_FS_F15(r5) ! 276: lfd f16, PCB_FS_F16(r5) ! 277: lfd f17, PCB_FS_F17(r5) ! 278: lfd f18, PCB_FS_F18(r5) ! 279: lfd f19, PCB_FS_F19(r5) ! 280: lfd f20, PCB_FS_F20(r5) ! 281: lfd f21, PCB_FS_F21(r5) ! 282: lfd f22, PCB_FS_F22(r5) ! 283: lfd f23, PCB_FS_F23(r5) ! 284: lfd f24, PCB_FS_F24(r5) ! 285: lfd f25, PCB_FS_F25(r5) ! 286: lfd f26, PCB_FS_F26(r5) ! 287: lfd f27, PCB_FS_F27(r5) ! 288: lfd f28, PCB_FS_F28(r5) ! 289: lfd f29, PCB_FS_F29(r5) ! 290: lfd f30, PCB_FS_F30(r5) ! 291: lfd f31, PCB_FS_F31(r5) ! 292: ! 293: /* Turn back on the FPU in the current user thread saved context */ ! 294: lwz r4, SS_SRR1(r5) ! 295: ori r4, r4, MASK(MSR_FP) /* bit is in low-order 16 */ ! 296: stw r4, SS_SRR1(r5) ! 297: ! 298: .L_fpu_restore_ret: ! 299: blr ! 300: ! 301: ! 302: /* ! 303: * fpu_switch() ! 304: * ! 305: * Jumped to by the floating-point unavailable exception handler to ! 306: * switch fpu context in a lazy manner. ! 307: * ! 308: * This code is run in virtual address mode with interrupts off. ! 309: * It is assumed that the pcb in question is in memory ! 310: * ! 311: * Upon exit, the code returns to the users context with the MSR_FP for the ! 312: * previous FPU owner disabled. ! 313: * ! 314: * ENTRY: VM switched ON ! 315: * Interrupts OFF ! 316: * original r1-3 saved in sprg1-3 ! 317: * original srr0 and srr1 saved in per_proc_info structure ! 318: * original cr saved in per_proc_info structure ! 319: * exception type saved in per_proc_info structure ! 320: * r1 = scratch ! 321: * r2 = virt addr of per_proc_info ! 322: * r3 = exception type (one of EXC_...) ! 323: * ! 324: * r1 is used as a temporary register throught this code, not as a stack ! 325: * pointer. ! 326: * ! 327: */ ! 328: ! 329: .text ! 330: ENTRY(fpu_switch, TAG_NO_FRAME_USED) ! 331: ! 332: #if DEBUG ! 333: lwz r3, PP_SAVE_SRR1(r2) ! 334: andi. r1, r3, MASK(MSR_PR) ! 335: bne+ .L_fpu_switch_user ! 336: bl EXT(fpu_panic) ! 337: .L_fpu_switch_user: ! 338: #endif /* DEBUG */ ! 339: ! 340: /* ! 341: * Turn the FPU back on ! 342: */ ! 343: mfmsr r3 ! 344: ori r3, r3, MASK(MSR_FP) /* bit is in low-order 16 */ ! 345: mtmsr r3 ! 346: isync ! 347: ! 348: /* See if the current thread owns the FPU, if so, just return */ ! 349: lwz r3, PP_FPU_PCB(r2) ! 350: ! 351: lwz r1, PP_CPU_DATA(r2) ! 352: lwz r1, CPU_ACTIVE_THREAD(r1) ! 353: lwz r1, THREAD_PCB(r1) ! 354: ! 355: cmpw CR0, r1, r3 /* If we own FPU, just return */ ! 356: beq CR0, .L_fpu_switch_return ! 357: cmpwi CR1, r3, 0 /* If no owner, skip save */ ! 358: beq CR1, .L_fpu_switch_load_state ! 359: ! 360: /* ! 361: * Identical code to that of fpu_save but is inlined ! 362: * to avoid creating a stack frame etc. ! 363: */ ! 364: stfd f0, PCB_FS_F0(r3) ! 365: stfd f1, PCB_FS_F1(r3) ! 366: stfd f2, PCB_FS_F2(r3) ! 367: stfd f3, PCB_FS_F3(r3) ! 368: stfd f4, PCB_FS_F4(r3) ! 369: stfd f5, PCB_FS_F5(r3) ! 370: stfd f6, PCB_FS_F6(r3) ! 371: stfd f7, PCB_FS_F7(r3) ! 372: mffs f0 /* fpscr in f0 low 32 bits*/ ! 373: stfd f8, PCB_FS_F8(r3) ! 374: stfd f9, PCB_FS_F9(r3) ! 375: stfd f10, PCB_FS_F10(r3) ! 376: stfd f11, PCB_FS_F11(r3) ! 377: stfd f12, PCB_FS_F12(r3) ! 378: stfd f13, PCB_FS_F13(r3) ! 379: stfd f14, PCB_FS_F14(r3) ! 380: stfd f15, PCB_FS_F15(r3) ! 381: stfd f0, PCB_FS_FPSCR(r3) /* Store junk 32 bits+fpscr */ ! 382: stfd f16, PCB_FS_F16(r3) ! 383: stfd f17, PCB_FS_F17(r3) ! 384: stfd f18, PCB_FS_F18(r3) ! 385: stfd f19, PCB_FS_F19(r3) ! 386: stfd f20, PCB_FS_F20(r3) ! 387: stfd f21, PCB_FS_F21(r3) ! 388: stfd f22, PCB_FS_F22(r3) ! 389: stfd f23, PCB_FS_F23(r3) ! 390: stfd f24, PCB_FS_F24(r3) ! 391: stfd f25, PCB_FS_F25(r3) ! 392: stfd f26, PCB_FS_F26(r3) ! 393: stfd f27, PCB_FS_F27(r3) ! 394: stfd f28, PCB_FS_F28(r3) ! 395: stfd f29, PCB_FS_F29(r3) ! 396: stfd f30, PCB_FS_F30(r3) ! 397: stfd f31, PCB_FS_F31(r3) ! 398: ! 399: stw r0, SS_R0(r1) ! 400: /* ! 401: * Turn off the FPU for the old owner ! 402: */ ! 403: lwz r0, SS_SRR1(r3) ! 404: rlwinm r0, r0, 0, MSR_FP_BIT+1, MSR_FP_BIT-1 ! 405: stw r0, SS_SRR1(r3) ! 406: ! 407: lwz r0, SS_R0(r1) ! 408: ! 409: /* Now load in the current threads state */ ! 410: ! 411: .L_fpu_switch_load_state: ! 412: ! 413: /* Store current PCB address in fpu_pcb to claim fpu for thread */ ! 414: stw r1, PP_FPU_PCB(r2) ! 415: ! 416: lfd f31, PCB_FS_FPSCR(r1) /* Load junk 32 bits+fpscr */ ! 417: lfd f0, PCB_FS_F0(r1) ! 418: lfd f1, PCB_FS_F1(r1) ! 419: lfd f2, PCB_FS_F2(r1) ! 420: lfd f3, PCB_FS_F3(r1) ! 421: lfd f4, PCB_FS_F4(r1) ! 422: lfd f5, PCB_FS_F5(r1) ! 423: lfd f6, PCB_FS_F6(r1) ! 424: lfd f7, PCB_FS_F7(r1) ! 425: mtfsf 0xff, f31 /* fpscr in f0 low 32 bits*/ ! 426: lfd f8, PCB_FS_F8(r1) ! 427: lfd f9, PCB_FS_F9(r1) ! 428: lfd f10, PCB_FS_F10(r1) ! 429: lfd f11, PCB_FS_F11(r1) ! 430: lfd f12, PCB_FS_F12(r1) ! 431: lfd f13, PCB_FS_F13(r1) ! 432: lfd f14, PCB_FS_F14(r1) ! 433: lfd f15, PCB_FS_F15(r1) ! 434: lfd f16, PCB_FS_F16(r1) ! 435: lfd f17, PCB_FS_F17(r1) ! 436: lfd f18, PCB_FS_F18(r1) ! 437: lfd f19, PCB_FS_F19(r1) ! 438: lfd f20, PCB_FS_F20(r1) ! 439: lfd f21, PCB_FS_F21(r1) ! 440: lfd f22, PCB_FS_F22(r1) ! 441: lfd f23, PCB_FS_F23(r1) ! 442: lfd f24, PCB_FS_F24(r1) ! 443: lfd f25, PCB_FS_F25(r1) ! 444: lfd f26, PCB_FS_F26(r1) ! 445: lfd f27, PCB_FS_F27(r1) ! 446: lfd f28, PCB_FS_F28(r1) ! 447: lfd f29, PCB_FS_F29(r1) ! 448: lfd f30, PCB_FS_F30(r1) ! 449: lfd f31, PCB_FS_F31(r1) ! 450: ! 451: .L_fpu_switch_return: ! 452: ! 453: /* the trampoline code takes r1-r3 from sprg1-3, and uses r1-3 ! 454: * as arguments */ ! 455: ! 456: /* Prepare to rfi to the exception exit routine, which is ! 457: * in physical address space */ ! 458: ! 459: addis r3, 0, ha16(EXT(exception_exit)) ! 460: addi r3, r3, lo16(EXT(exception_exit)) ! 461: lwz r3, 0(r3) ! 462: mtsrr0 r3 ! 463: li r3, MSR_VM_OFF ! 464: mtsrr1 r3 ! 465: ! 466: ! 467: lwz r1, PCB_SR0(r1) /* restore current sr0 */ ! 468: ! 469: lwz r3, PP_SAVE_CR(r2) ! 470: mtcrf 0xFF,r3 ! 471: lwz r3, PP_SAVE_SRR1(r2) ! 472: lwz r2, PP_SAVE_SRR0(r2) ! 473: /* Enable floating point for the thread we're returning to */ ! 474: ori r3, r3, MASK(MSR_FP) /* bit is in low-order 16 */ ! 475: ! 476: /* Return to the trapped context */ ! 477: rfi ! 478: ! 479: /* ! 480: * void fpu_disable(void) ! 481: * ! 482: * disable the fpu in the current msr ! 483: * ! 484: */ ! 485: ! 486: ENTRY(fpu_disable, TAG_NO_FRAME_USED) ! 487: ! 488: /* See if the current thread owns the FPU, if so, just return */ ! 489: mfsprg r2, 0 /* HACK - need to get around r2 problem */ ! 490: lwz r0, PP_FPU_PCB(r2) ! 491: cmpwi CR1, r0, 0 /* If no owner, skip save */ ! 492: bne CR1, .L_fpu_disable_not ! 493: ! 494: mfmsr r0 ! 495: rlwinm r0, r0, 0, MSR_FP_BIT+1, MSR_FP_BIT-1 ! 496: mtmsr r0 ! 497: isync ! 498: .L_fpu_disable_not: ! 499: blr ! 500: ! 501: ENTRY(fpu_disable_thread, TAG_NO_FRAME_USED) ! 502: ! 503: /* Mark the FPU as having no owner now */ ! 504: mfsprg r2, 0 /* HACK - need to get around r2 problem */ ! 505: ! 506: lwz r0, PP_FPU_PCB(r2) ! 507: lwz r3, PP_CPU_DATA(r2) ! 508: lwz r3, CPU_ACTIVE_THREAD(r3) ! 509: lwz r3, THREAD_PCB(r3) ! 510: ! 511: cmpw CR0, r0, r3 /* If we own FPU, disown it */ ! 512: bne CR0, .L_thread_not_own ! 513: ! 514: li r0, 0 ! 515: stw r0, PP_FPU_PCB(r2) ! 516: .L_thread_not_own: ! 517: ! 518: mfmsr r0 ! 519: rlwinm r0, r0, 0, MSR_FP_BIT+1, MSR_FP_BIT-1 ! 520: mtmsr r0 ! 521: isync ! 522: blr ! 523: ! 524: /* ! 525: * void lfs(fpsp,fpdp) ! 526: * ! 527: * load the single precision float to the double ! 528: * ! 529: * This routine is used by the alignment handler. ! 530: * ! 531: */ ! 532: ENTRY(lfs, TAG_NO_FRAME_USED) ! 533: lfs f1, 0(r3) ! 534: stfd f1, 0(r4) ! 535: blr ! 536: ! 537: /* ! 538: * fpsp stfs(fpdp,fpsp) ! 539: * ! 540: * store the double precision float to the single ! 541: * ! 542: * This routine is used by the alignment handler. ! 543: * ! 544: */ ! 545: ENTRY(stfs, TAG_NO_FRAME_USED) ! 546: lfd f1, 0(r3) ! 547: stfs f1, 0(r4) ! 548: blr ! 549:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.