+;
+; We come here to handle program exceptions
+;
+; When the program check is a trap instruction and it happens when
+; we are executing injected code, we need to check if it is an exit trap.
+; If it is, we need to populate the current savearea with some of the context from
+; the saved pre-inject savearea. This is needed because the current savearea will be
+; tossed as part of the pass up code. Additionally, because we will not be nullifying
+; the emulated instruction as we do with any other exception.
+;
+
+ .align 5
+
+ProgramChk: lwz r5,savesrr1+4(r13) ; Get the interrupt SRR1
+ lwz r3,ijsave(r2) ; Get the inject savearea top
+ lwz r4,ijsave+4(r2) ; And get the bottom of the inject savearea pointer
+ rlwimi r5,r5,15,31,31 ; Scoot trap flag down to a spare bit
+ rlwinm r3,r3,0,1,0 ; Copy low 32 bits of to top 32
+ li r0,0x0023 ; Get bits that match scooted trap flag, IR, and RI
+ and r0,r5,r0 ; Clear any extra SRR1 bits
+ rlwimi. r3,r4,0,0,31 ; Insert low part of 64-bit address in bottom 32 bits and see if ijsave is 0
+ cmplwi cr1,r0,1 ; Make sure we were IR off, RI off, and got a trap exception
+ crandc cr0_eq,cr1_eq,cr0_eq ; If we are injecting, ijsave will be non-zero and we had the trap bit set
+ mfsrr0 r4 ; Get the PC
+ bne++ cr0,mustem ; This is not an injection exit...
+
+ lwz r4,0(r4) ; Get the trap instruction
+ lis r5,hi16(ijtrap) ; Get high half of inject exit trap
+ ori r5,r5,lo16(ijtrap) ; And the low half
+ cmplw r4,r5 ; Correct trap instruction?
+ bne mustem ; No, not inject exit...
+
+ lwz r4,savesrr0(r3) ; Get the original SRR0
+ lwz r5,savesrr0+4(r3) ; And the rest of it
+ lwz r6,savesrr1(r3) ; Get the original SRR1
+ stw r4,savesrr0(r13) ; Set the new SRR0 to the original
+ lwz r4,savesrr1+4(r13) ; Get the bottom of the new SRR1
+ lwz r7,savesrr1+4(r3) ; Get the bottom of the original SRR1
+ li r11,T_INJECT_EXIT ; Set an inject exit exception
+ stw r5,savesrr0+4(r13) ; Set the new bottom of SRR0 to the original
+ rlwimi r7,r4,0,MSR_FP_BIT,MSR_FP_BIT ; Make sure we retain the current floating point enable bit
+ stw r6,savesrr1(r13) ; Save the top half of the original SRR1
+ sth r7,savesrr1+6(r13) ; And the last bottom
+ stw r11,saveexception(r13) ; Set the new the exception code
+ b PassUpTrap ; Go pass it on up...
+
+mustem: b EXT(Emulate) ; Go try to emulate this one...
+