Annotation of kernel/machdep/ppc/fpu.s, revision 1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.