-fptoss: lwz r25,SAVprefp(r24) ; Get previous savearea
-#if FPVECDBG
- lis r0,HIGH_ADDR(CutTrace) ; (TEST/DEBUG)
- li r2,0x3304 ; (TEST/DEBUG)
- oris r0,r0,LOW_ADDR(CutTrace) ; (TEST/DEBUG)
- mr r5,r25 ; (TEST/DEBUG)
- sc ; (TEST/DEBUG)
-#endif
- mr. r25,r25 ; Is there one?
- stw r25,ACT_MACT_FPU(r8) ; Set the new pointer
- beq fptoplvl ; Nope, we are at the top...
-#if FPVECDBG
- rlwinm. r0,r25,0,0,15 ; (TEST/DEBUG)
- bne+ notbadxxx2 ; (TEST/DEBUG)
- BREAKPOINT_TRAP ; (TEST/DEBUG)
-notbadxxx2: ; (TEST/DEBUG)
-#endif
- lwz r25,SAVlvlfp(r25) ; Get the new level
-
-fptoplvl: lwz r19,SAVflags(r24) ; Get the savearea flags
-#if FPVECDBG
- rlwinm. r0,r19,0,1,1 ; (TEST/DEBUG)
- bne+ donotdie3 ; (TEST/DEBUG)
- BREAKPOINT_TRAP ; (TEST/DEBUG)
-donotdie3: ; (TEST/DEBUG)
-#endif
+fpuchkena: bt-- cr2_eq,fpuhasdfrd ; Skip if deferred, R26 already set up...
+ mr r26,r20 ; Use the non-deferred value
+
+fpuhasdfrd:
+#if 0
+ rlwinm. r0,r29,0,MSR_PR_BIT,MSR_PR_BIT ; (TEST/DEBUG) Going into user state?
+ beq fpunusrstt ; (TEST/DEBUG) Nope...
+ lwz r23,FPUlevel(r26) ; (TEST/DEBUG) Get the level ID
+ lwz r24,FPUsave(r26) ; (TEST/DEBUG) Get the first savearea
+ mr. r23,r23 ; (TEST/DEBUG) Should be level 0
+ beq++ fpulvl0 ; (TEST/DEBUG) Yes...
+
+ lis r0,hi16(Choke) ; (TEST/DEBUG) Choke code
+ ori r0,r0,lo16(Choke) ; (TEST/DEBUG) and the rest
+ sc ; (TEST/DEBUG) System ABEND
+
+fpulvl0: mr. r24,r24 ; (TEST/DEBUG) Any context?
+ beq fpunusrstt ; (TEST/DEBUG) No...
+ lwz r23,SAVlevel(r24) ; (TEST/DEBUG) Get level of context
+ lwz r21,SAVprev+4(r24) ; (TEST/DEBUG) Get previous pointer
+ mr. r23,r23 ; (TEST/DEBUG) Is this our user context?
+ beq++ fpulvl0b ; (TEST/DEBUG) Yes...
+
+ lis r0,hi16(Choke) ; (TEST/DEBUG) Choke code
+ ori r0,r0,lo16(Choke) ; (TEST/DEBUG) and the rest
+ sc ; (TEST/DEBUG) System ABEND
+
+fpulvl0b: mr. r21,r21 ; (TEST/DEBUG) Is there a forward chain?
+ beq++ fpunusrstt ; (TEST/DEBUG) Nope...
+
+ lis r0,hi16(Choke) ; (TEST/DEBUG) Choke code
+ ori r0,r0,lo16(Choke) ; (TEST/DEBUG) and the rest
+ sc ; (TEST/DEBUG) System ABEND
+
+fpunusrstt: ; (TEST/DEBUG)
+#endif
+
+ lwz r21,FPUowner(r31) ; Get the ID of the live context
+ lwz r23,FPUlevel(r26) ; Get the level ID
+ lwz r24,FPUcpu(r26) ; Get the CPU that the context was last dispatched on
+ cmplw cr3,r26,r21 ; Do we have the live context?
+ cmplw r30,r23 ; Are we about to launch the live level?
+ bne-- cr3,chkvec ; No, can not possibly enable...
+ cmplw cr1,r19,r24 ; Was facility used on this processor last?
+ bne-- chkvec ; No, not live...
+ bne-- cr1,chkvec ; No, wrong cpu, have to enable later....
+
+ lwz r24,FPUsave(r26) ; Get the first savearea
+ mr. r24,r24 ; Any savearea?
+ beq++ fpuena ; Nope...
+ lwz r25,SAVlevel(r24) ; Get the level of savearea
+ lwz r0,SAVprev+4(r24) ; Get the previous
+
+ cmplw r30,r25 ; Is savearea for the level we are launching?
+ bne++ fpuena ; No, just go enable...
+
+ stw r0,FPUsave(r26) ; Pop the chain
+
+ rlwinm r3,r24,0,0,19 ; Find main savearea header
+
+ lwz r8,quickfret(r31) ; Get the first in quickfret list (top)
+ lwz r9,quickfret+4(r31) ; Get the first in quickfret list (bottom)
+ lwz r2,SACvrswap(r3) ; Get the virtual to real conversion (top)
+ lwz r3,SACvrswap+4(r3) ; Get the virtual to real conversion (bottom)
+ stw r8,SAVprev(r24) ; Link the old in (top)
+ stw r9,SAVprev+4(r24) ; Link the old in (bottom)
+ xor r3,r24,r3 ; Convert to physical
+ stw r2,quickfret(r31) ; Set the first in quickfret list (top)
+ stw r3,quickfret+4(r31) ; Set the first in quickfret list (bottom)