2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
31 Emulate instructions and traps.
33 Lovingly crafted by Bill Angell using traditional methods and only natural or recycled materials.
34 No animal products are used other than rendered otter bile and deep fried pork lard.
39 #include <ppc/proc_reg.h>
40 #include <ppc/exception.h>
41 #include <ppc/cpu_capabilities.h>
42 #include <mach/machine/vm_param.h>
48 ; General stuff what happens here:
49 ; 1) All general context saved, interrupts off, translation off
50 ; 2) Vector and floating point disabled, but there may be live context.
51 ; This code is responsible for saving and restoring what is used. This
52 ; includes exception states, java mode, etc.
53 ; 3) No attempt is made to resolve page faults. PTE misses are handled
54 ; automatically, but actual faults (ala copyin/copyout) are not. If
55 ; a fault does occur, the exception that caused entry to the emulation
56 ; routine is remapped to either an instruction or data miss (depending
57 ; upon the stage detected) and redrived through the exception handler.
58 ; The only time that an instruction fault can happen is when a different
59 ; processor removes a mapping between our original fault and when we
60 ; fetch the assisted instruction. For an assisted instruction, data
61 ; faults should not occur (except in the MP case). For a purely
62 ; emulated instruction, faults can occur.
72 bf-- pf64Bitb,emn64 ; Skip if not 64-bit
73 b EXT(Emulate64) ; Jump to the 64-bit code...
75 emn64: mfsprg r31,0 ; Get the per_proc
76 lwz r12,savesrr1+4(r13) ; Get the exception info
77 rlwinm. r0,r12,0,SRR1_PRG_ILL_INS_BIT,SRR1_PRG_ILL_INS_BIT ; Emulation candidate?
78 lwz r30,dgFlags(0) ; Get the flags
79 beq+ eExit ; Nope, do not try to emulate...
81 rlwinm. r0,r30,0,enaDiagEMb,enaDiagEMb ; Do we want to try to emulate something?
82 mfsprg r28,2 ; Get the processor features
83 beq+ eExit ; No emulation allowed...
85 rlwinm. r28,r28,0,pfAltivecb,pfAltivecb ; Do we have Altivec on this machine?
86 beq eNoVect ; Nope, no Altivec...
88 dssall ; We need to kill streams because we are going to flip to problem state
91 eNoVect: bl eIFetch ; Get the instruction image
92 bne- eRedriveAsISI ; Go redrive this as an ISI...
94 rlwinm. r0,r10,0,0,5 ; See if we have the "special" op code here
95 rlwinm r20,r10,16,22,31 ; Set rS/rD and rA
96 bne+ eExit ; Not special op, ignore...
98 rlwinm r0,r10,31,22,31 ; Extract the sub op code
100 rlwimi r20,r10,14,15,16 ; Move bits 29 and 30 of instruction to 15 and 16 of DSISR
101 cmplwi r0,790 ; lhbrx?
102 rlwimi r20,r10,8,17,17 ; Move bit 25 to bit 17
103 cror cr1_eq,cr1_eq,cr0_eq ; Remember
104 cmplwi r0,534 ; lwbrx?
105 rlwimi r20,r10,3,18,21 ; Move bit 21-24 to bit 18-21
106 cror cr1_eq,cr1_eq,cr0_eq ; Remember
107 cmplwi r0,918 ; sthbrx?
108 cror cr1_eq,cr1_eq,cr0_eq ; Remember
109 cmplwi r0,662 ; stwbrx?
110 cror cr1_eq,cr1_eq,cr0_eq ; Remember
111 cmplwi r0,1014 ; dcbz?
112 cror cr1_eq,cr1_eq,cr0_eq ; Remember
113 cmplwi r0,533 ; lswx?
114 cror cr1_eq,cr1_eq,cr0_eq ; Remember
115 cmplwi r0,661 ; stswx?
116 cror cr1_eq,cr1_eq,cr0_eq ; Remember
117 bne cr1_eq,eNotIndex ; Go check non-index forms...
119 rlwinm. r21,r10,19,24,28 ; Extract index to rA to build EA
120 rlwinm r22,r10,24,24,28 ; Extract index to rB
121 addi r24,r13,saver0+4 ; Point to the start of registers
122 li r19,0 ; Assume 0 base
123 beq eZeroBase ; Yes...
124 lwzx r19,r24,r21 ; Get the base register value
126 eZeroBase: lwzx r22,r24,r22 ; Get the index value
127 add r22,r22,r19 ; Get DAR
128 b eFinishUp ; Done, go finish up...
130 eNotIndex: cmplwi r0,725 ; stswi?
131 cror cr1_eq,cr1_eq,cr0_eq ; Remember
132 cmplwi r0,597 ; lswi?
133 cror cr1_eq,cr1_eq,cr0_eq ; Remember
134 bne cr1,eExit ; Not one we handle...
136 rlwinm. r21,r10,19,24,28 ; Extract index to rA to build EA
137 addi r24,r13,saver0+4 ; Point to the start of registers
138 li r22,0 ; Assume 0 base
139 beq eFinishUp ; Yes, it is...
140 lwzx r22,r24,r21 ; Get the base register value
142 eFinishUp: stw r20,savedsisr(r13) ; Set the DSISR
143 li r11,T_ALIGNMENT ; Get the exception code
144 stw r22,savedar+4(r13) ; Save the DAR
145 stw r11,saveexception(r13) ; Set the exception code
146 b EXT(AlignAssist) ; Go emulate the handler...
149 eExit: b EXT(EmulExit) ; Just return for now...
153 ; Fetch the failing instruction.
154 ; Image returned in R10 if CR0_EQ is false, otherwise, an ISI should be generated/
155 ; The cr bit kernAccess is set if this was a kernel access.
156 ; R1 has the DSISR if access failed.
161 eIFetch: lwz r23,savesrr1+4(r13) ; Get old MSR
162 mflr r28 ; Save return
164 rlwinm. r22,r23,0,MSR_PR_BIT,MSR_PR_BIT ; Within kernel?
166 mfmsr r30 ; Save the MSR for now
167 lwz r23,savesrr0+4(r13) ; Get instruction address
169 ori r22,r30,lo16(MASK(MSR_DR)|MASK(MSR_RI)) ; Set RI and DR onto access MSR
171 crset cr0_eq ; Set this to see if we failed
172 mtmsr r22 ; Flip DR, RI, and maybe PR on
175 lwz r10,0(r23) ; Fetch the instruction
177 mtmsr r30 ; Trans and RI off
180 mtlr r28 ; Restore the LR
181 blr ; Return with instruction image in R10
189 lwz r6,savesrr1+4(r13) ; Get the srr1 value
190 lwz r4,SAVflags(r13) ; Pick up the flags
191 li r11,T_INSTRUCTION_ACCESS ; Set failing instruction fetch code
192 rlwimi r6,r1,0,0,4 ; Move the DSISR bits to the SRR1
193 oris r4,r4,hi16(SAVredrive) ; Set the redrive bit
194 stw r11,saveexception(r13) ; Set the replacement code
195 stw r4,SAVflags(r13) ; Set redrive request
196 stw r6,savesrr1+4(r13) ; Set the srr1 value
197 b EXT(EmulExit) ; Bail out to handle ISI...
201 ; This code emulates instructions that have failed because of operand
202 ; alignment. We decode the DSISR to figure out what we need to do.
205 ; 0001FC00 - Instruction designation
215 ; 000003E0 - Target/Source register
216 ; 0000001F - Register to update if update form
220 .globl EXT(AlignAssist)
223 bf-- pf64Bitb,aan64 ; Skip if not 64-bit
224 b EXT(AlignAssist64) ; Jump to the 64-bit code...
226 aan64: lwz r20,savedsisr(r13) ; Get the DSISR
227 li r0,0 ; Assume we emulate
228 mfsprg r31,0 ; Get the per_proc
229 mtcrf 0x10,r20 ; Put instruction ID in CR for later
230 lwz r21,spcFlags(r31) ; Grab the special flags
231 stw r0,savemisc3(r13) ; Assume that we emulate ok
232 mtcrf 0x08,r20 ; Put instruction ID in CR for later
233 rlwinm. r0,r21,0,runningVMbit,runningVMbit ; Are we running a VM?
234 mtcrf 0x04,r20 ; Put instruction ID in CR for later
235 lwz r22,savesrr1+4(r13) ; Get the SRR1
236 bne- aaPassAlong ; We are in a VM, no emulation for alignment exceptions...
237 lwz r19,dgFlags(0) ; Get the diagnostics flags
238 crxor iFloat,iOptype1,iOptype2 ; Set this to 0 if both bits are either 0 or 1
239 mr r26,r20 ; Save the DSISR
240 rlwinm. r0,r22,0,MSR_SE_BIT,MSR_SE_BIT ; Were we single stepping?
241 lwz r23,savedar+4(r13) ; Pick up the address that we want to access
242 crnot traceInst,cr0_eq ; Remember if trace is on
244 rlwinm. r0,r19,0,enaNotifyEMb,enaNotifyEMb ; Should we notify that an alignment exception happened?
245 mfmsr r30 ; Save the MSR for now
246 crnot iNotify,cr0_eq ; Remember to tell someone we did this
247 li r29,emfp0 ; Point to work area
248 crxor iFloat,iFloat,iOptype3 ; Set true if we have a floating point instruction
249 dcbz r29,r31 ; Clear and allocate a cache line for us to work in
250 rlwinm r24,r20,3,24,28 ; Get displacement to register to update if update form
251 rlwimi r20,r20,24,28,28 ; Move load/store indication to the bottom of index
252 ori r22,r30,lo16(MASK(MSR_DR)|MASK(MSR_RI)) ; Set RI onto access MSR
253 rlwimi r20,r20,26,27,27 ; Move single/double indication to just above the bottom
254 lis r29,hi16(EXT(aaFPopTable)) ; High part of FP branch table
255 bf- iFloat,aaNotFloat ; This is not a floating point instruction...
256 ori r29,r29,lo16(EXT(aaFPopTable)) ; Low part of FP branch table
258 rlwimi r29,r20,0,22,28 ; Index into table based upon register||iDouble||iStore
259 mtctr r29 ; Get set to call the function
260 bt iStore,aaFPstore ; This is an FP store...
263 ; Here we handle floating point loads
266 aaFPload: crset cr0_eq ; Set this to see if we failed
267 mtmsr r22 ; Flip DR, RI
270 lwz r10,0(r23) ; Get the first word
271 bf- cr0_eq,aaLdNotDbl ; Jump out if we DSIed...
272 bf iDouble,aaLdNotDbl ; this is not a double...
273 lwz r11,4(r23) ; Get the second half
275 aaLdNotDbl: mr r4,r0 ; Save the DAR if we failed the access
277 mtmsr r30 ; Turn off translation again
280 bf- cr0_eq,aaRedriveAsDSI ; Go redrive this as a DSI...
282 stw r10,emfp0(r31) ; Save the first half
283 stw r11,emfp0+4(r31) ; Save the second half, just in case we need it
285 bctrl ; Go set the target FP register
287 b aaComExit ; All done, go exit...
290 ; Here we handle floating point stores
295 aaFPstore: bctrl ; Go save the source FP register
297 lwz r10,emfp0(r31) ; Get first word
298 crandc iDouble,iDouble,iOptype4 ; Change to 4-byte access if stfiwx
299 lwz r11,emfp0+4(r31) ; and the second
300 bf+ iOptype4,aaNotstfiwx ; This is not a stfiwx...
301 mr r10,r11 ; The stfiwx wants to store the second half
304 crset cr0_eq ; Set this to see if we failed
305 mtmsr r22 ; Flip DR, RI
308 stw r10,0(r23) ; Save the first word
309 bf- cr0_eq,aaStNotDbl ; Jump out if we DSIed...
310 bf iDouble,aaStNotDbl ; this is not a double...
311 stw r11,4(r23) ; Save the second half
313 aaStNotDbl: mr r4,r0 ; Save the DAR if we failed the access
317 bf- cr0_eq,aaRedriveAsDSI ; Go redrive this as a DSI...
320 ; Common exit routines
323 aaComExit: lwz r10,savesrr0+4(r13) ; Get the failing instruction address
324 add r24,r24,r13 ; Offset to update register
325 li r11,T_IN_VAIN ; Assume we are all done
326 addi r10,r10,4 ; Step to the next instruction
327 bf iUpdate,aaComExNU ; Skip if not an update form...
328 stw r23,saver0+4(r24) ; Update the target
330 aaComExNU: lwz r9,SAVflags(r13) ; Get the flags
331 stw r10,savesrr0+4(r13) ; Set new PC
332 bt- traceInst,aaComExitrd ; We are tracing, go emulate trace...
333 bf+ iNotify,aaComExGo ; Nothing special here, go...
335 li r11,T_ALIGNMENT ; Set the we just did an alignment exception....
337 aaComExGo: b EXT(EmulExit) ; We are done, no tracing on...
341 ; This is not a floating point operation
343 ; The table of these emulation routines is indexed by taking the low order 4 bits of
344 ; the instruction code in the DSISR and subtracting 7. If this comes up negative,
345 ; the instruction is not to be emulated. Then we add bit 0 of the code * 4. This
346 ; gives us a fairly compact and almost unique index. Both lwm and stmw map to 0 so
347 ; that one needs to be further reduced, and we end up with holes at a few indexes.
353 lis r19,hi16(aaEmTable) ; Point to high part of table address
354 rlwinm r3,r26,24,26,29 ; Isolate last 4 bits of op type * 4
355 rlwimi r19,r26,20,27,27 ; Get bit 0 of instruction code * 4 into bottom of table base
356 addic. r3,r3,-28 ; Subtract 7*4 to adjust index
357 ori r19,r19,lo16(aaEmTable) ; Low part of table address
358 blt- aaPassAlong ; We do not handle any of these (lwarx, stwcx., eciwx, ecowx)...
359 add r19,r19,r3 ; Point to emulation routine
360 rlwinm r18,r26,30,24,28 ; Get the target/source register displacement
362 mtctr r19 ; Set the routine address
364 bctr ; Go emulate the instruction...
367 ; This is the table of non-floating point emulation routines.
368 ; It is indexed by the code immediately above.
373 b aaLmwStmw ; This for lmw/stmw
374 b aaLswx ; This for lwwx
375 b aaLswi ; This for lswi
376 b aaStswx ; This for stswx
377 b aaStswi ; This for stswi
378 b aaLwbrx ; This for lwbrx
379 b aaPassAlong ; This an invalid index (6)
380 b aaStwbrx ; This for stwbrx
381 b aaPassAlong ; This an invalid index (8)
382 b aaLhbrx ; This for lhbrx
383 b aaPassAlong ; This an invalid index (A)
384 b aaSthbrx ; This for sthbrx
385 b aaDcbz ; This for dcbz
386 b aaPassAlong ; This an invalid index (D)
387 b aaPassAlong ; This an invalid index (E)
388 b aaPassAlong ; This an invalid index (F)
392 ; Here we handle the set up for the lmw and stmw. After that, we split off to the
393 ; individual routines.
395 ; Note also that after some set up, all of the string instructions come through here as well.
400 rlwinm r17,r18,31,1,29 ; Convert doublword based index to words
401 li r28,0 ; Set no extra bytes to move (used for string instructions)
402 subfic r17,r17,32*4 ; Calculate the length of the transfer
404 aaLSComm: addi r19,r13,saver0+4 ; Offset to registers in savearea
405 mr r16,r23 ; Make a hunk pointer
407 bt iUpdate,aaStmw ; This is the stmw...
413 aaLmwNxt: cmplwi cr1,r17,8*4 ; Is there enough to move 8?
414 blt- cr1,aaLmwNxtH ; Not enough for a full hunk...
415 subi r17,r17,8*4 ; Back off for another hunk
417 crset cr0_eq ; Set this to see if we failed
418 mtmsr r22 ; Flip DR, RI
421 lwz r2,0(r16) ; Load word 0
422 bf- cr0_eq,aaLmwB1 ; Error, bail...
423 lwz r15,4(r16) ; Load word 1
424 bf- cr0_eq,aaLmwB1 ; Error, bail...
425 lwz r14,8(r16) ; Load word 2
426 bf- cr0_eq,aaLmwB1 ; Error, bail...
427 lwz r5,12(r16) ; Load word 3
428 bf- cr0_eq,aaLmwB1 ; Error, bail...
429 lwz r6,16(r16) ; Load word 4
430 bf- cr0_eq,aaLmwB1 ; Error, bail...
431 lwz r7,20(r16) ; Load word 5
432 bf- cr0_eq,aaLmwB1 ; Error, bail...
433 lwz r8,24(r16) ; Load word 6
434 bf- cr0_eq,aaLmwB1 ; Error, bail...
435 lwz r9,28(r16) ; Load word 7
437 aaLmwB1: mr r4,r0 ; Remember DAR, jus in case we failed the access
438 mtmsr r30 ; Turn off DR, RI
441 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
443 addi r16,r16,8*4 ; Point up to next input aread
445 stwx r2,r19,r18 ; Store register
446 addi r18,r18,8 ; Next register
447 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
448 stwx r15,r19,r18 ; Store register
449 addi r18,r18,8 ; Next register
450 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
451 stwx r14,r19,r18 ; Store register
452 addi r18,r18,8 ; Next register
453 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
454 stwx r5,r19,r18 ; Store register
455 addi r18,r18,8 ; Next register
456 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
457 stwx r6,r19,r18 ; Store register
458 addi r18,r18,8 ; Next register
459 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
460 stwx r7,r19,r18 ; Store register
461 addi r18,r18,8 ; Next register
462 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
463 stwx r8,r19,r18 ; Store register
464 addi r18,r18,8 ; Next register
465 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
466 stwx r9,r19,r18 ; Store register
467 addi r18,r18,8 ; Next register
468 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
470 b aaLmwNxt ; Do the next hunk...
474 aaLmwNxtH: cmplwi cr1,r17,4*4 ; Do we have 4 left?
475 blt cr1,aaLmwL4 ; Nope...
477 subi r17,r17,4*4 ; Set count properly
479 crset cr0_eq ; Set this to see if we failed
480 mtmsr r22 ; Flip DR, RI, and maybe PR on
483 lwz r2,0(r16) ; Load word 0
484 bf- cr0_eq,aaLmwB2 ; Error, bail...
485 lwz r15,4(r16) ; Load word 1
486 bf- cr0_eq,aaLmwB2 ; Error, bail...
487 lwz r14,8(r16) ; Load word 2
488 bf- cr0_eq,aaLmwB2 ; Error, bail...
489 lwz r5,12(r16) ; Load word 3
491 aaLmwB2: mr r4,r0 ; Remember DAR, jus in case we failed the access
492 mtmsr r30 ; Turn off DR, RI
495 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
497 addi r16,r16,4*4 ; Point up to next input aread
499 stwx r2,r19,r18 ; Store register
500 addi r18,r18,8 ; Next register
501 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
502 stwx r15,r19,r18 ; Store register
503 addi r18,r18,8 ; Next register
504 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
505 stwx r14,r19,r18 ; Store register
506 addi r18,r18,8 ; Next register
507 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
508 stwx r5,r19,r18 ; Store register
509 addi r18,r18,8 ; Next register
510 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
512 aaLmwL4: or. r5,r17,r28 ; Do we have anything left?
513 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three full words left?
514 cmplwi cr2,r17,0 ; Do we have no full words left?
515 beq aaComExit ; Nothing left...
517 crset cr0_eq ; Set this to see if we failed
518 mtmsr r22 ; Flip DR, RI, and maybe PR on
521 beq- cr2,aaLmwBy ; No full words, get bytes...
523 lwz r2,0(r16) ; Pick up first word
524 bf- cr0_eq,aaLmwDn ; Read failed, escape...
525 addi r16,r16,4 ; Next input location
526 blt cr1,aaLmwBy ; We only had one, we are done...
528 lwz r15,0(r16) ; Pick up second word
529 bf- cr0_eq,aaLmwDn ; Read failed, escape...
530 addi r16,r16,4 ; Next input location
531 beq cr1,aaLmwBy ; We had two, we are done...
533 lwz r14,0(r16) ; Load word 3
534 addi r16,r16,4 ; Next input location
536 aaLmwBy: cmplwi cr2,r28,0 ; Any trailing bytes to do?
537 li r8,0 ; Clear second trailing byte
538 cmplwi cr1,r28,2 ; Check for 1, 2, or 3
539 li r9,0 ; Clear third trailing byte
540 beq+ cr2,aaLmwDn ; No trailing bytes...
542 lbz r5,0(r16) ; Pick up first trailing byte
543 bf- cr0_eq,aaLmwDn ; Read failed, escape...
544 blt cr1,aaLmwDn ; We only had one, we are done...
546 lbz r8,1(r16) ; Pick up second trailing byte
547 bf- cr0_eq,aaLmwDn ; Read failed, escape...
548 beq cr1,aaLmwDn ; We had two, we are done...
550 lbz r9,2(r16) ; Get last trailing byte
553 aaLmwDn: rlwinm r5,r5,24,0,7 ; Move first byte to top
554 cmplwi cr2,r17,0 ; Any full words to do?
555 mr r4,r0 ; Remember DAR, just in case we failed the access
556 rlwimi r9,r8,8,16,23 ; Move second byte above third byte
557 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three full words left?
558 mr r3,r30 ; Set the normal MSR
559 rlwimi r5,r9,8,8,23 ; Move bytes 1 and 2 after 0
561 mtmsr r30 ; Turn off DR, RI
564 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
566 beq- cr2,aaLmwCb ; No full words, copy bytes...
568 stwx r2,r19,r18 ; Store register
569 addi r18,r18,8 ; Next register
570 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
571 blt cr1,aaLmwCb ; We only had one, we are done...
573 stwx r15,r19,r18 ; Store register
574 addi r18,r18,8 ; Next register
575 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
576 beq cr1,aaLmwCb ; We had two, we are done...
578 stwx r14,r19,r18 ; Store register
579 addi r18,r18,8 ; Next register
580 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
582 aaLmwCb: mr. r28,r28 ; Any trailing bytes to do?
583 beq+ aaComExit ; Nope, leave...
585 stwx r5,r19,r18 ; Store register
587 b aaComExit ; We are done....
590 ; Store multiple word
596 crclr iUpdate ; Make sure we do not think this is an update form
598 aaStmwNxt: cmplwi cr1,r17,8*4 ; Is there enough to move 8?
599 blt- cr1,aaStmwNxtH ; Not enough for a full hunk...
600 subi r17,r17,8*4 ; Back off for another hunk
602 lwzx r2,r19,r18 ; Store register
603 addi r18,r18,8 ; Next register
604 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
605 lwzx r15,r19,r18 ; Store register
606 addi r18,r18,8 ; Next register
607 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
608 lwzx r14,r19,r18 ; Store register
609 addi r18,r18,8 ; Next register
610 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
611 lwzx r5,r19,r18 ; Store register
612 addi r18,r18,8 ; Next register
613 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
614 lwzx r6,r19,r18 ; Store register
615 addi r18,r18,8 ; Next register
616 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
617 lwzx r7,r19,r18 ; Store register
618 addi r18,r18,8 ; Next register
619 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
620 lwzx r8,r19,r18 ; Store register
621 addi r18,r18,8 ; Next register
622 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
623 lwzx r9,r19,r18 ; Store register
624 addi r18,r18,8 ; Next register
625 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
627 crset cr0_eq ; Set this to see if we failed
628 mtmsr r22 ; Flip DR, RI, and maybe PR on
631 stw r2,0(r16) ; Store word 0
632 bf- cr0_eq,aaStmwB1 ; Error, bail...
633 stw r15,4(r16) ; Store word 1
634 bf- cr0_eq,aaStmwB1 ; Error, bail...
635 stw r14,8(r16) ; Store word 2
636 bf- cr0_eq,aaStmwB1 ; Error, bail...
637 stw r5,12(r16) ; Store word 3
638 bf- cr0_eq,aaStmwB1 ; Error, bail...
639 stw r6,16(r16) ; Store word 4
640 bf- cr0_eq,aaStmwB1 ; Error, bail...
641 stw r7,20(r16) ; Store word 5
642 bf- cr0_eq,aaStmwB1 ; Error, bail...
643 stw r8,24(r16) ; Store word 6
644 bf- cr0_eq,aaStmwB1 ; Error, bail...
645 stw r9,28(r16) ; Store word 7
647 addi r16,r16,8*4 ; Point up to next output aread
650 aaStmwB1: mr r4,r0 ; Remember DAR, jus in case we failed the access
651 mtmsr r30 ; Normal MSR
654 bt- cr0_eq,aaStmwNxt ; We have more to do and no failed access...
655 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
659 aaStmwNxtH: cmplwi cr1,r17,(4*4) ; Do we have at least 4 left?
660 blt cr1,aaStmwL4 ; Nope...
661 subi r17,r17,4*4 ; Set count properly
663 lwzx r2,r19,r18 ; Store register
664 addi r18,r18,8 ; Next register
665 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
666 lwzx r15,r19,r18 ; Store register
667 addi r18,r18,8 ; Next register
668 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
669 lwzx r14,r19,r18 ; Store register
670 addi r18,r18,8 ; Next register
671 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
672 lwzx r5,r19,r18 ; Store register
673 addi r18,r18,8 ; Next register
674 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
676 crset cr0_eq ; Set this to see if we failed
677 mtmsr r22 ; Flip DR, RI
680 stw r2,0(r16) ; Store word 0
681 bf- cr0_eq,aaStmwB2 ; Error, bail...
682 stw r15,4(r16) ; Store word 1
683 bf- cr0_eq,aaStmwB2 ; Error, bail...
684 stw r14,8(r16) ; Store word 2
685 bf- cr0_eq,aaStmwB2 ; Error, bail...
686 stw r5,12(r16) ; Store word 3
688 addi r16,r16,4*4 ; Point up to next input aread
690 aaStmwB2: mr r4,r0 ; Remember DAR, jus in case we failed the access
691 mtmsr r30 ; Normal MSR
694 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
696 aaStmwL4: or. r5,r17,r28 ; Do we have anything left to do?
697 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three left?
698 cmplwi cr2,r17,0 ; Do we have no full words left?
699 beq aaComExit ; Nothing left...
701 beq- cr2,aaStmwBy1 ; No full words, check out bytes
703 lwzx r2,r19,r18 ; Store register
704 addi r18,r18,8 ; Next register
705 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
706 blt cr1,aaStmwBy1 ; We only had one, go save it...
708 lwzx r15,r19,r18 ; Store register
709 addi r18,r18,8 ; Next register
710 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
711 beq cr1,aaStmwBy1 ; We had two, go save it...
713 lwzx r14,r19,r18 ; Store register
714 addi r18,r18,8 ; Next register
715 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
717 aaStmwBy1: mr. r28,r28 ; Do we have any trailing bytes?
718 beq+ aaStmwSt ; Nope...
720 lwzx r5,r19,r18 ; Yes, pick up one extra register
722 aaStmwSt: crset cr0_eq ; Set this to see if we failed
723 mtmsr r22 ; Flip DR, RI
726 beq- cr2,aaStmwBy2 ; No words, check trailing bytes...
728 stw r2,0(r16) ; Save first word
729 bf- cr0_eq,aaStmwDn ; Store failed, escape...
730 addi r16,r16,4 ; Bump sink
731 blt cr1,aaStmwBy2 ; We only had one, we are done...
733 stw r15,0(r16) ; Save second word
734 bf- cr0_eq,aaStmwDn ; Store failed, escape...
735 addi r16,r16,4 ; Bump sink
736 beq cr1,aaStmwBy2 ; We had two, we are done...
738 stw r14,0(r16) ; Save third word
739 bf- cr0_eq,aaStmwDn ; Store failed, escape...
740 addi r16,r16,4 ; Bump sink
742 aaStmwBy2: rlwinm r2,r5,8,24,31 ; Get byte 0
743 cmplwi cr2,r28,0 ; Any trailing bytes to do?
744 rlwinm r14,r5,24,24,31 ; Get byte 3
745 li r8,0 ; Clear second trailing byte
746 cmplwi cr1,r28,2 ; Check for 1, 2, or 3
747 li r9,0 ; Clear third trailing byte
748 beq+ cr2,aaStmwDn ; No trailing bytes...
749 rlwinm r15,r5,16,24,31 ; Get byte 1
751 stb r2,0(r16) ; Save first byte
752 bf- cr0_eq,aaStmwDn ; Read failed, escape...
753 blt cr1,aaStmwDn ; We only had one, we are done...
755 stb r15,1(r16) ; Save second byte
756 bf- cr0_eq,aaStmwDn ; Read failed, escape...
757 beq cr1,aaStmwDn ; We had two, we are done...
759 stb r14,2(r16) ; Save third byte
761 aaStmwDn: mr r4,r0 ; Remember DAR, jus in case we failed the access
762 mtmsr r30 ; Normal MSR
765 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
767 b aaComExit ; We are done....
771 ; Load String Indexed
776 aaLswx: lwz r17,savexer+4(r13) ; Pick up the XER
777 crclr iUpdate ; Make sure we think this the load form
778 rlwinm. r25,r17,0,25,31 ; Get the number of bytes to load
779 rlwinm r28,r17,0,30,31 ; Get the number of bytes past an even word
780 beq- aaComExit ; Do nothing if 0 length...
781 xor r17,r25,r28 ; Round down to an even word boundary
782 b aaLSComm ; Join up with common load/store code...
786 ; Load String Immediate
791 aaLswi: mr r9,r23 ; Save the DAR
792 bl eIFetch ; Get the instruction image
793 bne- eRedriveAsISI ; Go redrive this as an ISI...
794 rlwinm r25,r10,21,27,31 ; Get the number of bytes to load
795 crclr iUpdate ; Make sure we think this the load form
796 subi r25,r25,1 ; Back off by 1
797 rlwinm r25,r25,0,27,31 ; Clear back down
798 addi r25,r25,1 ; Add back the 1 to convert 0 to 32
799 rlwinm r28,r25,0,30,31 ; Get the number of bytes past an even word
800 xor r17,r25,r28 ; Round down to an even word boundary
801 mr r23,r9 ; Move back the DAR
802 b aaLSComm ; Join up with common load/store code...
805 ; Store String Indexed
810 aaStswx: lwz r17,savexer+4(r13) ; Pick up the XER
811 crclr iUpdate ; Make sure this is clear in case we have 0 length
812 rlwinm. r25,r17,0,25,31 ; Get the number of bytes to load
813 rlwinm r28,r17,0,30,31 ; Get the number of bytes past an even word
814 beq- aaComExit ; Do nothing if 0 length...
815 xor r17,r25,r28 ; Round down to an even word boundary
816 crset iUpdate ; Make sure we think this the store form
817 b aaLSComm ; Join up with common load/store code...
821 ; Store String Immediate
826 aaStswi: mr r9,r23 ; Save the DAR
827 bl eIFetch ; Get the instruction image
828 bne- eRedriveAsISI ; Go redrive this as an ISI...
829 rlwinm r25,r10,21,27,31 ; Get the number of bytes to load
830 crclr iUpdate ; Make sure we think this the load form
831 subi r25,r25,1 ; Back off by 1
832 rlwinm r25,r25,0,27,31 ; Clear back down
833 addi r25,r25,1 ; Add back the 1 to convert 0 to 32
834 rlwinm r28,r25,21,30,31 ; Get the number of bytes past an even word
835 xor r17,r25,r28 ; Round down to an even word boundary
836 mr r23,r9 ; Move back the DAR
837 b aaLSComm ; Join up with common load/store code...
841 ; Load byte-reversed word
847 add r18,r18,r13 ; Index to source register
849 crset cr0_eq ; Set this to see if we failed
850 mtmsr r22 ; Flip DR, RI, and maybe PR on
853 lwz r11,0(r23) ; Load the word
855 mr r4,r0 ; Save the DAR if we failed the access
856 mtmsr r30 ; Restore normal MSR
859 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
861 rlwinm r10,r11,8,0,31 ; Get byte 0 to 3 and byte 2 to 1
862 rlwimi r10,r11,24,16,23 ; Move byte 1 to byte 2
863 rlwimi r10,r11,24,0,7 ; Move byte 3 to byte 0
865 stw r10,saver0+4(r18) ; Set the register
867 b aaComExit ; All done, go exit...
872 ; Store byte-reversed word
878 add r18,r18,r13 ; Index to source register
879 lwz r11,saver0+4(r18) ; Get the register to store
881 rlwinm r10,r11,8,0,31 ; Get byte 0 to 3 and byte 2 to 1
882 rlwimi r10,r11,24,16,23 ; Move byte 1 to byte 2
883 rlwimi r10,r11,24,0,7 ; Move byte 3 to byte 0
885 crset cr0_eq ; Set this to see if we failed
886 mtmsr r22 ; Flip DR, RI, and maybe PR on
889 stw r10,0(r23) ; Store the reversed halfword
891 mr r4,r0 ; Save the DAR if we failed the access
892 mtmsr r30 ; Restore normal MSR
895 bt+ cr0_eq,aaComExit ; All done, go exit...
896 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
901 ; Load byte-reversed halfword
907 add r18,r18,r13 ; Index to source register
909 crset cr0_eq ; Set this to see if we failed
910 mtmsr r22 ; Flip DR, RI, and maybe PR on
913 lhz r11,0(r23) ; Load the halfword
915 mr r4,r0 ; Save the DAR if we failed the access
916 mtmsr r30 ; Restore normal MSR
919 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
921 rlwinm r10,r11,8,16,23 ; Rotate bottom byte up one and clear everything else
922 rlwimi r10,r11,24,24,31 ; Put old second from bottom into bottom
924 stw r10,saver0+4(r18) ; Set the register
926 b aaComExit ; All done, go exit...
930 ; Store byte-reversed halfword
936 add r18,r18,r13 ; Index to source register
937 lwz r10,saver0+4(r18) ; Get the register to store
938 rlwinm r10,r10,8,0,31 ; Rotate bottom byte up one
939 rlwimi r10,r10,16,24,31 ; Put old second from bottom into bottom
941 crset cr0_eq ; Set this to see if we failed
942 mtmsr r22 ; Flip DR, RI, and maybe PR on
945 sth r10,0(r23) ; Store the reversed halfword
947 mr r4,r0 ; Save the DAR if we failed the access
948 mtmsr r30 ; Restore normal MSR
951 bt+ cr0_eq,aaComExit ; All done, go exit...
952 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
955 ; Data cache block zero
961 lwz r0,savesrr0+4(r13) ; get instruction address
962 li r4,_COMM_PAGE_BASE_ADDRESS
963 rlwinm r23,r23,0,0,26 ; Round EA back to a 32-byte boundary
964 sub r4,r0,r4 ; compute instruction offset from base of commpage
965 cmplwi r4,_COMM_PAGE_AREA_USED ; did fault occur in commpage?
966 bge+ aaDcbz1 ; skip if not in commpage
967 lwz r4,savecr(r13) ; if we take a dcbz in the commpage...
968 rlwinm r4,r4,0,0,27 ; ...clear users cr7 as a flag for commpage code
971 crset cr0_eq ; Set this to see if we failed
972 li r0,0 ; Clear this out
973 mtmsr r22 ; Flip DR, RI, and maybe PR on
976 stw r0,0(r23) ; Clear word
977 bne- aaDcbzXit ; Got DSI, we are stopping...
978 stw r0,4(r23) ; Clear word
979 bne- aaDcbzXit ; Got DSI, we are stopping...
980 stw r0,8(r23) ; Clear word
981 bne- aaDcbzXit ; Got DSI, we are stopping...
982 stw r0,12(r23) ; Clear word
983 bne- aaDcbzXit ; Got DSI, we are stopping...
984 stw r0,16(r23) ; Clear word
985 bne- aaDcbzXit ; Got DSI, we are stopping...
986 stw r0,20(r23) ; Clear word
987 bne- aaDcbzXit ; Got DSI, we are stopping...
988 stw r0,24(r23) ; Clear word
989 bne- aaDcbzXit ; Got DSI, we are stopping...
990 stw r0,28(r23) ; Clear word
992 aaDcbzXit: mr r4,r0 ; Save the DAR if we failed the access
993 mtmsr r30 ; Restore normal MSR
996 crclr iUpdate ; Make sure we do not think this is an update form
998 bt+ cr0_eq,aaComExit ; All done, go exit...
999 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
1003 ; Unhandled alignment exception, pass it along
1007 li r0,1 ; Indicate that we failed to emulate
1008 stw r0,savemisc3(r13) ; Assume that we emulate ok
1015 ; We go here to emulate a trace exception after we have handled alignment error
1021 oris r9,r9,hi16(SAVredrive) ; Set the redrive bit
1022 li r11,T_TRACE ; Set trace interrupt
1023 rlwinm r12,r12,0,16,31 ; Clear top half of SRR1
1024 stw r9,SAVflags(r13) ; Set the flags
1025 stw r11,saveexception(r13) ; Set the exception code
1026 b EXT(EmulExit) ; Exit and do trace interrupt...
1034 mr r20,r1 ; Save the DSISR
1036 lwz r4,SAVflags(r13) ; Pick up the flags
1037 li r11,T_DATA_ACCESS ; Set failing data access code
1038 oris r4,r4,hi16(SAVredrive) ; Set the redrive bit
1039 stw r20,savedsisr(r13) ; Set the DSISR of failed access
1040 stw r21,savedar+4(r13) ; Set the address of the failed access
1041 stw r11,saveexception(r13) ; Set the replacement code
1042 stw r4,SAVflags(r13) ; Set redrive request
1043 b EXT(EmulExit) ; Bail out to handle ISI...
1048 ; Table of functions to load or store floating point registers
1049 ; This table is indexed reg||size||dir. That means that each
1050 ; like load/store pair (e.g., lfd f31/stfd f31) are within the same
1051 ; quadword, which is the current ifetch size. We expect most of the
1052 ; unaligned accesses to be part of copies, therefore, with this
1053 ; organization, we will save the ifetch of the store after the load.
1056 .align 10 ; Make sure we are on a 1k boundary
1057 .globl EXT(aaFPopTable)
1060 lfs f0,emfp0(r31) ; Load single variant
1063 stfs f0,emfp0(r31) ; Store single variant
1066 lfd f0,emfp0(r31) ; Load double variant
1069 stfd f0,emfp0(r31) ; Store double variant
1072 lfs f1,emfp0(r31) ; Load single variant
1075 stfs f1,emfp0(r31) ; Store single variant
1078 lfd f1,emfp0(r31) ; Load double variant
1081 stfd f1,emfp0(r31) ; Store double variant
1084 lfs f2,emfp0(r31) ; Load single variant
1087 stfs f2,emfp0(r31) ; Store single variant
1090 lfd f2,emfp0(r31) ; Load double variant
1093 stfd f2,emfp0(r31) ; Store double variant
1096 lfs f3,emfp0(r31) ; Load single variant
1099 stfs f3,emfp0(r31) ; Store single variant
1102 lfd f3,emfp0(r31) ; Load double variant
1105 stfd f3,emfp0(r31) ; Store double variant
1108 lfs f4,emfp0(r31) ; Load single variant
1111 stfs f4,emfp0(r31) ; Store single variant
1114 lfd f4,emfp0(r31) ; Load double variant
1117 stfd f4,emfp0(r31) ; Store double variant
1120 lfs f5,emfp0(r31) ; Load single variant
1123 stfs f5,emfp0(r31) ; Store single variant
1126 lfd f5,emfp0(r31) ; Load double variant
1129 stfd f5,emfp0(r31) ; Store double variant
1132 lfs f6,emfp0(r31) ; Load single variant
1135 stfs f6,emfp0(r31) ; Store single variant
1138 lfd f6,emfp0(r31) ; Load double variant
1141 stfd f6,emfp0(r31) ; Store double variant
1144 lfs f7,emfp0(r31) ; Load single variant
1147 stfs f7,emfp0(r31) ; Store single variant
1150 lfd f7,emfp0(r31) ; Load double variant
1153 stfd f7,emfp0(r31) ; Store double variant
1156 lfs f8,emfp0(r31) ; Load single variant
1159 stfs f8,emfp0(r31) ; Store single variant
1162 lfd f8,emfp0(r31) ; Load double variant
1165 stfd f8,emfp0(r31) ; Store double variant
1168 lfs f9,emfp0(r31) ; Load single variant
1171 stfs f9,emfp0(r31) ; Store single variant
1174 lfd f9,emfp0(r31) ; Load double variant
1177 stfd f9,emfp0(r31) ; Store double variant
1180 lfs f10,emfp0(r31) ; Load single variant
1183 stfs f10,emfp0(r31) ; Store single variant
1186 lfd f10,emfp0(r31) ; Load double variant
1189 stfd f10,emfp0(r31) ; Store double variant
1192 lfs f11,emfp0(r31) ; Load single variant
1195 stfs f11,emfp0(r31) ; Store single variant
1198 lfd f11,emfp0(r31) ; Load double variant
1201 stfd f11,emfp0(r31) ; Store double variant
1204 lfs f12,emfp0(r31) ; Load single variant
1207 stfs f12,emfp0(r31) ; Store single variant
1210 lfd f12,emfp0(r31) ; Load double variant
1213 stfd f12,emfp0(r31) ; Store double variant
1216 lfs f13,emfp0(r31) ; Load single variant
1219 stfs f13,emfp0(r31) ; Store single variant
1222 lfd f13,emfp0(r31) ; Load double variant
1225 stfd f13,emfp0(r31) ; Store double variant
1228 lfs f14,emfp0(r31) ; Load single variant
1231 stfs f14,emfp0(r31) ; Store single variant
1234 lfd f14,emfp0(r31) ; Load double variant
1237 stfd f14,emfp0(r31) ; Store double variant
1240 lfs f15,emfp0(r31) ; Load single variant
1243 stfs f15,emfp0(r31) ; Store single variant
1246 lfd f15,emfp0(r31) ; Load double variant
1249 stfd f15,emfp0(r31) ; Store double variant
1252 lfs f16,emfp0(r31) ; Load single variant
1255 stfs f16,emfp0(r31) ; Store single variant
1258 lfd f16,emfp0(r31) ; Load double variant
1261 stfd f16,emfp0(r31) ; Store double variant
1264 lfs f17,emfp0(r31) ; Load single variant
1267 stfs f17,emfp0(r31) ; Store single variant
1270 lfd f17,emfp0(r31) ; Load double variant
1273 stfd f17,emfp0(r31) ; Store double variant
1276 lfs f18,emfp0(r31) ; Load single variant
1279 stfs f18,emfp0(r31) ; Store single variant
1282 lfd f18,emfp0(r31) ; Load double variant
1285 stfd f18,emfp0(r31) ; Store double variant
1288 lfs f19,emfp0(r31) ; Load single variant
1291 stfs f19,emfp0(r31) ; Store single variant
1294 lfd f19,emfp0(r31) ; Load double variant
1297 stfd f19,emfp0(r31) ; Store double variant
1300 lfs f20,emfp0(r31) ; Load single variant
1303 stfs f20,emfp0(r31) ; Store single variant
1306 lfd f20,emfp0(r31) ; Load double variant
1309 stfd f20,emfp0(r31) ; Store double variant
1312 lfs f21,emfp0(r31) ; Load single variant
1315 stfs f21,emfp0(r31) ; Store single variant
1318 lfd f21,emfp0(r31) ; Load double variant
1321 stfd f21,emfp0(r31) ; Store double variant
1324 lfs f22,emfp0(r31) ; Load single variant
1327 stfs f22,emfp0(r31) ; Store single variant
1330 lfd f22,emfp0(r31) ; Load double variant
1333 stfd f22,emfp0(r31) ; Store double variant
1336 lfs f23,emfp0(r31) ; Load single variant
1339 stfs f23,emfp0(r31) ; Store single variant
1342 lfd f23,emfp0(r31) ; Load double variant
1345 stfd f23,emfp0(r31) ; Store double variant
1348 lfs f24,emfp0(r31) ; Load single variant
1351 stfs f24,emfp0(r31) ; Store single variant
1354 lfd f24,emfp0(r31) ; Load double variant
1357 stfd f24,emfp0(r31) ; Store double variant
1360 lfs f25,emfp0(r31) ; Load single variant
1363 stfs f25,emfp0(r31) ; Store single variant
1366 lfd f25,emfp0(r31) ; Load double variant
1369 stfd f25,emfp0(r31) ; Store double variant
1372 lfs f26,emfp0(r31) ; Load single variant
1375 stfs f26,emfp0(r31) ; Store single variant
1378 lfd f26,emfp0(r31) ; Load double variant
1381 stfd f26,emfp0(r31) ; Store double variant
1384 lfs f27,emfp0(r31) ; Load single variant
1387 stfs f27,emfp0(r31) ; Store single variant
1390 lfd f27,emfp0(r31) ; Load double variant
1393 stfd f27,emfp0(r31) ; Store double variant
1396 lfs f28,emfp0(r31) ; Load single variant
1399 stfs f28,emfp0(r31) ; Store single variant
1402 lfd f28,emfp0(r31) ; Load double variant
1405 stfd f28,emfp0(r31) ; Store double variant
1408 lfs f29,emfp0(r31) ; Load single variant
1411 stfs f29,emfp0(r31) ; Store single variant
1414 lfd f29,emfp0(r31) ; Load double variant
1417 stfd f29,emfp0(r31) ; Store double variant
1420 lfs f30,emfp0(r31) ; Load single variant
1423 stfs f30,emfp0(r31) ; Store single variant
1426 lfd f30,emfp0(r31) ; Load double variant
1429 stfd f30,emfp0(r31) ; Store double variant
1432 lfs f31,emfp0(r31) ; Load single variant
1435 stfs f31,emfp0(r31) ; Store single variant
1438 lfd f31,emfp0(r31) ; Load double variant
1441 stfd f31,emfp0(r31) ; Store double variant