2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_OSREFERENCE_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
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
33 Emulate instructions and traps.
35 Lovingly crafted by Bill Angell using traditional methods and only natural or recycled materials.
36 No animal products are used other than rendered otter bile and deep fried pork lard.
41 #include <ppc/proc_reg.h>
42 #include <ppc/exception.h>
43 #include <ppc/cpu_capabilities.h>
44 #include <mach/machine/vm_param.h>
50 ; General stuff what happens here:
51 ; 1) All general context saved, interrupts off, translation off
52 ; 2) Vector and floating point disabled, but there may be live context.
53 ; This code is responsible for saving and restoring what is used. This
54 ; includes exception states, java mode, etc.
55 ; 3) No attempt is made to resolve page faults. PTE misses are handled
56 ; automatically, but actual faults (ala copyin/copyout) are not. If
57 ; a fault does occur, the exception that caused entry to the emulation
58 ; routine is remapped to either an instruction or data miss (depending
59 ; upon the stage detected) and redrived through the exception handler.
60 ; The only time that an instruction fault can happen is when a different
61 ; processor removes a mapping between our original fault and when we
62 ; fetch the assisted instruction. For an assisted instruction, data
63 ; faults should not occur (except in the MP case). For a purely
64 ; emulated instruction, faults can occur.
74 bf-- pf64Bitb,emn64 ; Skip if not 64-bit
75 b EXT(Emulate64) ; Jump to the 64-bit code...
77 emn64: mfsprg r31,0 ; Get the per_proc
78 lwz r12,savesrr1+4(r13) ; Get the exception info
79 rlwinm. r0,r12,0,SRR1_PRG_ILL_INS_BIT,SRR1_PRG_ILL_INS_BIT ; Emulation candidate?
80 lwz r30,dgFlags(0) ; Get the flags
81 beq+ eExit ; Nope, do not try to emulate...
83 rlwinm. r0,r30,0,enaDiagEMb,enaDiagEMb ; Do we want to try to emulate something?
84 mfsprg r28,2 ; Get the processor features
85 beq+ eExit ; No emulation allowed...
87 rlwinm. r28,r28,0,pfAltivecb,pfAltivecb ; Do we have Altivec on this machine?
88 beq eNoVect ; Nope, no Altivec...
90 dssall ; We need to kill streams because we are going to flip to problem state
93 eNoVect: bl eIFetch ; Get the instruction image
94 bne- eRedriveAsISI ; Go redrive this as an ISI...
96 rlwinm. r0,r10,0,0,5 ; See if we have the "special" op code here
97 rlwinm r20,r10,16,22,31 ; Set rS/rD and rA
98 bne+ eExit ; Not special op, ignore...
100 rlwinm r0,r10,31,22,31 ; Extract the sub op code
102 rlwimi r20,r10,14,15,16 ; Move bits 29 and 30 of instruction to 15 and 16 of DSISR
103 cmplwi r0,790 ; lhbrx?
104 rlwimi r20,r10,8,17,17 ; Move bit 25 to bit 17
105 cror cr1_eq,cr1_eq,cr0_eq ; Remember
106 cmplwi r0,534 ; lwbrx?
107 rlwimi r20,r10,3,18,21 ; Move bit 21-24 to bit 18-21
108 cror cr1_eq,cr1_eq,cr0_eq ; Remember
109 cmplwi r0,918 ; sthbrx?
110 cror cr1_eq,cr1_eq,cr0_eq ; Remember
111 cmplwi r0,662 ; stwbrx?
112 cror cr1_eq,cr1_eq,cr0_eq ; Remember
113 cmplwi r0,1014 ; dcbz?
114 cror cr1_eq,cr1_eq,cr0_eq ; Remember
115 cmplwi r0,533 ; lswx?
116 cror cr1_eq,cr1_eq,cr0_eq ; Remember
117 cmplwi r0,661 ; stswx?
118 cror cr1_eq,cr1_eq,cr0_eq ; Remember
119 bne cr1_eq,eNotIndex ; Go check non-index forms...
121 rlwinm. r21,r10,19,24,28 ; Extract index to rA to build EA
122 rlwinm r22,r10,24,24,28 ; Extract index to rB
123 addi r24,r13,saver0+4 ; Point to the start of registers
124 li r19,0 ; Assume 0 base
125 beq eZeroBase ; Yes...
126 lwzx r19,r24,r21 ; Get the base register value
128 eZeroBase: lwzx r22,r24,r22 ; Get the index value
129 add r22,r22,r19 ; Get DAR
130 b eFinishUp ; Done, go finish up...
132 eNotIndex: cmplwi r0,725 ; stswi?
133 cror cr1_eq,cr1_eq,cr0_eq ; Remember
134 cmplwi r0,597 ; lswi?
135 cror cr1_eq,cr1_eq,cr0_eq ; Remember
136 bne cr1,eExit ; Not one we handle...
138 rlwinm. r21,r10,19,24,28 ; Extract index to rA to build EA
139 addi r24,r13,saver0+4 ; Point to the start of registers
140 li r22,0 ; Assume 0 base
141 beq eFinishUp ; Yes, it is...
142 lwzx r22,r24,r21 ; Get the base register value
144 eFinishUp: stw r20,savedsisr(r13) ; Set the DSISR
145 li r11,T_ALIGNMENT ; Get the exception code
146 stw r22,savedar+4(r13) ; Save the DAR
147 stw r11,saveexception(r13) ; Set the exception code
148 b EXT(AlignAssist) ; Go emulate the handler...
151 eExit: b EXT(EmulExit) ; Just return for now...
155 ; Fetch the failing instruction.
156 ; Image returned in R10 if CR0_EQ is false, otherwise, an ISI should be generated/
157 ; The cr bit kernAccess is set if this was a kernel access.
158 ; R1 has the DSISR if access failed.
163 eIFetch: lwz r23,savesrr1+4(r13) ; Get old MSR
164 mflr r28 ; Save return
166 rlwinm. r22,r23,0,MSR_PR_BIT,MSR_PR_BIT ; Within kernel?
168 mfmsr r30 ; Save the MSR for now
169 lwz r23,savesrr0+4(r13) ; Get instruction address
171 ori r22,r30,lo16(MASK(MSR_DR)|MASK(MSR_RI)) ; Set RI and DR onto access MSR
173 crset cr0_eq ; Set this to see if we failed
174 mtmsr r22 ; Flip DR, RI, and maybe PR on
177 lwz r10,0(r23) ; Fetch the instruction
179 mtmsr r30 ; Trans and RI off
182 mtlr r28 ; Restore the LR
183 blr ; Return with instruction image in R10
191 lwz r6,savesrr1+4(r13) ; Get the srr1 value
192 lwz r4,SAVflags(r13) ; Pick up the flags
193 li r11,T_INSTRUCTION_ACCESS ; Set failing instruction fetch code
194 rlwimi r6,r1,0,0,4 ; Move the DSISR bits to the SRR1
195 oris r4,r4,hi16(SAVredrive) ; Set the redrive bit
196 stw r11,saveexception(r13) ; Set the replacement code
197 stw r4,SAVflags(r13) ; Set redrive request
198 stw r6,savesrr1+4(r13) ; Set the srr1 value
199 b EXT(EmulExit) ; Bail out to handle ISI...
203 ; This code emulates instructions that have failed because of operand
204 ; alignment. We decode the DSISR to figure out what we need to do.
207 ; 0001FC00 - Instruction designation
217 ; 000003E0 - Target/Source register
218 ; 0000001F - Register to update if update form
222 .globl EXT(AlignAssist)
225 bf-- pf64Bitb,aan64 ; Skip if not 64-bit
226 b EXT(AlignAssist64) ; Jump to the 64-bit code...
228 aan64: lwz r20,savedsisr(r13) ; Get the DSISR
229 li r0,0 ; Assume we emulate
230 mfsprg r31,0 ; Get the per_proc
231 mtcrf 0x10,r20 ; Put instruction ID in CR for later
232 lwz r21,spcFlags(r31) ; Grab the special flags
233 stw r0,savemisc3(r13) ; Assume that we emulate ok
234 mtcrf 0x08,r20 ; Put instruction ID in CR for later
235 rlwinm. r0,r21,0,runningVMbit,runningVMbit ; Are we running a VM?
236 mtcrf 0x04,r20 ; Put instruction ID in CR for later
237 lwz r22,savesrr1+4(r13) ; Get the SRR1
238 bne- aaPassAlong ; We are in a VM, no emulation for alignment exceptions...
239 lwz r19,dgFlags(0) ; Get the diagnostics flags
240 crxor iFloat,iOptype1,iOptype2 ; Set this to 0 if both bits are either 0 or 1
241 mr r26,r20 ; Save the DSISR
242 rlwinm. r0,r22,0,MSR_SE_BIT,MSR_SE_BIT ; Were we single stepping?
243 lwz r23,savedar+4(r13) ; Pick up the address that we want to access
244 crnot traceInst,cr0_eq ; Remember if trace is on
246 rlwinm. r0,r19,0,enaNotifyEMb,enaNotifyEMb ; Should we notify that an alignment exception happened?
247 mfmsr r30 ; Save the MSR for now
248 crnot iNotify,cr0_eq ; Remember to tell someone we did this
249 li r29,emfp0 ; Point to work area
250 crxor iFloat,iFloat,iOptype3 ; Set true if we have a floating point instruction
251 dcbz r29,r31 ; Clear and allocate a cache line for us to work in
252 rlwinm r24,r20,3,24,28 ; Get displacement to register to update if update form
253 rlwimi r20,r20,24,28,28 ; Move load/store indication to the bottom of index
254 ori r22,r30,lo16(MASK(MSR_DR)|MASK(MSR_RI)) ; Set RI onto access MSR
255 rlwimi r20,r20,26,27,27 ; Move single/double indication to just above the bottom
256 lis r29,hi16(EXT(aaFPopTable)) ; High part of FP branch table
257 bf- iFloat,aaNotFloat ; This is not a floating point instruction...
258 ori r29,r29,lo16(EXT(aaFPopTable)) ; Low part of FP branch table
260 rlwimi r29,r20,0,22,28 ; Index into table based upon register||iDouble||iStore
261 mtctr r29 ; Get set to call the function
262 bt iStore,aaFPstore ; This is an FP store...
265 ; Here we handle floating point loads
268 aaFPload: crset cr0_eq ; Set this to see if we failed
269 mtmsr r22 ; Flip DR, RI
272 lwz r10,0(r23) ; Get the first word
273 bf- cr0_eq,aaLdNotDbl ; Jump out if we DSIed...
274 bf iDouble,aaLdNotDbl ; this is not a double...
275 lwz r11,4(r23) ; Get the second half
277 aaLdNotDbl: mr r4,r0 ; Save the DAR if we failed the access
279 mtmsr r30 ; Turn off translation again
282 bf- cr0_eq,aaRedriveAsDSI ; Go redrive this as a DSI...
284 stw r10,emfp0(r31) ; Save the first half
285 stw r11,emfp0+4(r31) ; Save the second half, just in case we need it
287 bctrl ; Go set the target FP register
289 b aaComExit ; All done, go exit...
292 ; Here we handle floating point stores
297 aaFPstore: bctrl ; Go save the source FP register
299 lwz r10,emfp0(r31) ; Get first word
300 crandc iDouble,iDouble,iOptype4 ; Change to 4-byte access if stfiwx
301 lwz r11,emfp0+4(r31) ; and the second
302 bf+ iOptype4,aaNotstfiwx ; This is not a stfiwx...
303 mr r10,r11 ; The stfiwx wants to store the second half
306 crset cr0_eq ; Set this to see if we failed
307 mtmsr r22 ; Flip DR, RI
310 stw r10,0(r23) ; Save the first word
311 bf- cr0_eq,aaStNotDbl ; Jump out if we DSIed...
312 bf iDouble,aaStNotDbl ; this is not a double...
313 stw r11,4(r23) ; Save the second half
315 aaStNotDbl: mr r4,r0 ; Save the DAR if we failed the access
319 bf- cr0_eq,aaRedriveAsDSI ; Go redrive this as a DSI...
322 ; Common exit routines
325 aaComExit: lwz r10,savesrr0+4(r13) ; Get the failing instruction address
326 add r24,r24,r13 ; Offset to update register
327 li r11,T_IN_VAIN ; Assume we are all done
328 addi r10,r10,4 ; Step to the next instruction
329 bf iUpdate,aaComExNU ; Skip if not an update form...
330 stw r23,saver0+4(r24) ; Update the target
332 aaComExNU: lwz r9,SAVflags(r13) ; Get the flags
333 stw r10,savesrr0+4(r13) ; Set new PC
334 bt- traceInst,aaComExitrd ; We are tracing, go emulate trace...
335 bf+ iNotify,aaComExGo ; Nothing special here, go...
337 li r11,T_ALIGNMENT ; Set the we just did an alignment exception....
339 aaComExGo: b EXT(EmulExit) ; We are done, no tracing on...
343 ; This is not a floating point operation
345 ; The table of these emulation routines is indexed by taking the low order 4 bits of
346 ; the instruction code in the DSISR and subtracting 7. If this comes up negative,
347 ; the instruction is not to be emulated. Then we add bit 0 of the code * 4. This
348 ; gives us a fairly compact and almost unique index. Both lwm and stmw map to 0 so
349 ; that one needs to be further reduced, and we end up with holes at a few indexes.
355 lis r19,hi16(aaEmTable) ; Point to high part of table address
356 rlwinm r3,r26,24,26,29 ; Isolate last 4 bits of op type * 4
357 rlwimi r19,r26,20,27,27 ; Get bit 0 of instruction code * 4 into bottom of table base
358 addic. r3,r3,-28 ; Subtract 7*4 to adjust index
359 ori r19,r19,lo16(aaEmTable) ; Low part of table address
360 blt- aaPassAlong ; We do not handle any of these (lwarx, stwcx., eciwx, ecowx)...
361 add r19,r19,r3 ; Point to emulation routine
362 rlwinm r18,r26,30,24,28 ; Get the target/source register displacement
364 mtctr r19 ; Set the routine address
366 bctr ; Go emulate the instruction...
369 ; This is the table of non-floating point emulation routines.
370 ; It is indexed by the code immediately above.
375 b aaLmwStmw ; This for lmw/stmw
376 b aaLswx ; This for lwwx
377 b aaLswi ; This for lswi
378 b aaStswx ; This for stswx
379 b aaStswi ; This for stswi
380 b aaLwbrx ; This for lwbrx
381 b aaPassAlong ; This an invalid index (6)
382 b aaStwbrx ; This for stwbrx
383 b aaPassAlong ; This an invalid index (8)
384 b aaLhbrx ; This for lhbrx
385 b aaPassAlong ; This an invalid index (A)
386 b aaSthbrx ; This for sthbrx
387 b aaDcbz ; This for dcbz
388 b aaPassAlong ; This an invalid index (D)
389 b aaPassAlong ; This an invalid index (E)
390 b aaPassAlong ; This an invalid index (F)
394 ; Here we handle the set up for the lmw and stmw. After that, we split off to the
395 ; individual routines.
397 ; Note also that after some set up, all of the string instructions come through here as well.
402 rlwinm r17,r18,31,1,29 ; Convert doublword based index to words
403 li r28,0 ; Set no extra bytes to move (used for string instructions)
404 subfic r17,r17,32*4 ; Calculate the length of the transfer
406 aaLSComm: addi r19,r13,saver0+4 ; Offset to registers in savearea
407 mr r16,r23 ; Make a hunk pointer
409 bt iUpdate,aaStmw ; This is the stmw...
415 aaLmwNxt: cmplwi cr1,r17,8*4 ; Is there enough to move 8?
416 blt- cr1,aaLmwNxtH ; Not enough for a full hunk...
417 subi r17,r17,8*4 ; Back off for another hunk
419 crset cr0_eq ; Set this to see if we failed
420 mtmsr r22 ; Flip DR, RI
423 lwz r2,0(r16) ; Load word 0
424 bf- cr0_eq,aaLmwB1 ; Error, bail...
425 lwz r15,4(r16) ; Load word 1
426 bf- cr0_eq,aaLmwB1 ; Error, bail...
427 lwz r14,8(r16) ; Load word 2
428 bf- cr0_eq,aaLmwB1 ; Error, bail...
429 lwz r5,12(r16) ; Load word 3
430 bf- cr0_eq,aaLmwB1 ; Error, bail...
431 lwz r6,16(r16) ; Load word 4
432 bf- cr0_eq,aaLmwB1 ; Error, bail...
433 lwz r7,20(r16) ; Load word 5
434 bf- cr0_eq,aaLmwB1 ; Error, bail...
435 lwz r8,24(r16) ; Load word 6
436 bf- cr0_eq,aaLmwB1 ; Error, bail...
437 lwz r9,28(r16) ; Load word 7
439 aaLmwB1: mr r4,r0 ; Remember DAR, jus in case we failed the access
440 mtmsr r30 ; Turn off DR, RI
443 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
445 addi r16,r16,8*4 ; Point up to next input aread
447 stwx r2,r19,r18 ; Store register
448 addi r18,r18,8 ; Next register
449 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
450 stwx r15,r19,r18 ; Store register
451 addi r18,r18,8 ; Next register
452 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
453 stwx r14,r19,r18 ; Store register
454 addi r18,r18,8 ; Next register
455 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
456 stwx r5,r19,r18 ; Store register
457 addi r18,r18,8 ; Next register
458 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
459 stwx r6,r19,r18 ; Store register
460 addi r18,r18,8 ; Next register
461 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
462 stwx r7,r19,r18 ; Store register
463 addi r18,r18,8 ; Next register
464 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
465 stwx r8,r19,r18 ; Store register
466 addi r18,r18,8 ; Next register
467 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
468 stwx r9,r19,r18 ; Store register
469 addi r18,r18,8 ; Next register
470 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
472 b aaLmwNxt ; Do the next hunk...
476 aaLmwNxtH: cmplwi cr1,r17,4*4 ; Do we have 4 left?
477 blt cr1,aaLmwL4 ; Nope...
479 subi r17,r17,4*4 ; Set count properly
481 crset cr0_eq ; Set this to see if we failed
482 mtmsr r22 ; Flip DR, RI, and maybe PR on
485 lwz r2,0(r16) ; Load word 0
486 bf- cr0_eq,aaLmwB2 ; Error, bail...
487 lwz r15,4(r16) ; Load word 1
488 bf- cr0_eq,aaLmwB2 ; Error, bail...
489 lwz r14,8(r16) ; Load word 2
490 bf- cr0_eq,aaLmwB2 ; Error, bail...
491 lwz r5,12(r16) ; Load word 3
493 aaLmwB2: mr r4,r0 ; Remember DAR, jus in case we failed the access
494 mtmsr r30 ; Turn off DR, RI
497 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
499 addi r16,r16,4*4 ; Point up to next input aread
501 stwx r2,r19,r18 ; Store register
502 addi r18,r18,8 ; Next register
503 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
504 stwx r15,r19,r18 ; Store register
505 addi r18,r18,8 ; Next register
506 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
507 stwx r14,r19,r18 ; Store register
508 addi r18,r18,8 ; Next register
509 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
510 stwx r5,r19,r18 ; Store register
511 addi r18,r18,8 ; Next register
512 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
514 aaLmwL4: or. r5,r17,r28 ; Do we have anything left?
515 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three full words left?
516 cmplwi cr2,r17,0 ; Do we have no full words left?
517 beq aaComExit ; Nothing left...
519 crset cr0_eq ; Set this to see if we failed
520 mtmsr r22 ; Flip DR, RI, and maybe PR on
523 beq- cr2,aaLmwBy ; No full words, get bytes...
525 lwz r2,0(r16) ; Pick up first word
526 bf- cr0_eq,aaLmwDn ; Read failed, escape...
527 addi r16,r16,4 ; Next input location
528 blt cr1,aaLmwBy ; We only had one, we are done...
530 lwz r15,0(r16) ; Pick up second word
531 bf- cr0_eq,aaLmwDn ; Read failed, escape...
532 addi r16,r16,4 ; Next input location
533 beq cr1,aaLmwBy ; We had two, we are done...
535 lwz r14,0(r16) ; Load word 3
536 addi r16,r16,4 ; Next input location
538 aaLmwBy: cmplwi cr2,r28,0 ; Any trailing bytes to do?
539 li r8,0 ; Clear second trailing byte
540 cmplwi cr1,r28,2 ; Check for 1, 2, or 3
541 li r9,0 ; Clear third trailing byte
542 beq+ cr2,aaLmwDn ; No trailing bytes...
544 lbz r5,0(r16) ; Pick up first trailing byte
545 bf- cr0_eq,aaLmwDn ; Read failed, escape...
546 blt cr1,aaLmwDn ; We only had one, we are done...
548 lbz r8,1(r16) ; Pick up second trailing byte
549 bf- cr0_eq,aaLmwDn ; Read failed, escape...
550 beq cr1,aaLmwDn ; We had two, we are done...
552 lbz r9,2(r16) ; Get last trailing byte
555 aaLmwDn: rlwinm r5,r5,24,0,7 ; Move first byte to top
556 cmplwi cr2,r17,0 ; Any full words to do?
557 mr r4,r0 ; Remember DAR, just in case we failed the access
558 rlwimi r9,r8,8,16,23 ; Move second byte above third byte
559 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three full words left?
560 mr r3,r30 ; Set the normal MSR
561 rlwimi r5,r9,8,8,23 ; Move bytes 1 and 2 after 0
563 mtmsr r30 ; Turn off DR, RI
566 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
568 beq- cr2,aaLmwCb ; No full words, copy bytes...
570 stwx r2,r19,r18 ; Store register
571 addi r18,r18,8 ; Next register
572 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
573 blt cr1,aaLmwCb ; We only had one, we are done...
575 stwx r15,r19,r18 ; Store register
576 addi r18,r18,8 ; Next register
577 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
578 beq cr1,aaLmwCb ; We had two, we are done...
580 stwx r14,r19,r18 ; Store register
581 addi r18,r18,8 ; Next register
582 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
584 aaLmwCb: mr. r28,r28 ; Any trailing bytes to do?
585 beq+ aaComExit ; Nope, leave...
587 stwx r5,r19,r18 ; Store register
589 b aaComExit ; We are done....
592 ; Store multiple word
598 crclr iUpdate ; Make sure we do not think this is an update form
600 aaStmwNxt: cmplwi cr1,r17,8*4 ; Is there enough to move 8?
601 blt- cr1,aaStmwNxtH ; Not enough for a full hunk...
602 subi r17,r17,8*4 ; Back off for another hunk
604 lwzx r2,r19,r18 ; Store register
605 addi r18,r18,8 ; Next register
606 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
607 lwzx r15,r19,r18 ; Store register
608 addi r18,r18,8 ; Next register
609 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
610 lwzx r14,r19,r18 ; Store register
611 addi r18,r18,8 ; Next register
612 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
613 lwzx r5,r19,r18 ; Store register
614 addi r18,r18,8 ; Next register
615 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
616 lwzx r6,r19,r18 ; Store register
617 addi r18,r18,8 ; Next register
618 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
619 lwzx r7,r19,r18 ; Store register
620 addi r18,r18,8 ; Next register
621 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
622 lwzx r8,r19,r18 ; Store register
623 addi r18,r18,8 ; Next register
624 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
625 lwzx r9,r19,r18 ; Store register
626 addi r18,r18,8 ; Next register
627 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
629 crset cr0_eq ; Set this to see if we failed
630 mtmsr r22 ; Flip DR, RI, and maybe PR on
633 stw r2,0(r16) ; Store word 0
634 bf- cr0_eq,aaStmwB1 ; Error, bail...
635 stw r15,4(r16) ; Store word 1
636 bf- cr0_eq,aaStmwB1 ; Error, bail...
637 stw r14,8(r16) ; Store word 2
638 bf- cr0_eq,aaStmwB1 ; Error, bail...
639 stw r5,12(r16) ; Store word 3
640 bf- cr0_eq,aaStmwB1 ; Error, bail...
641 stw r6,16(r16) ; Store word 4
642 bf- cr0_eq,aaStmwB1 ; Error, bail...
643 stw r7,20(r16) ; Store word 5
644 bf- cr0_eq,aaStmwB1 ; Error, bail...
645 stw r8,24(r16) ; Store word 6
646 bf- cr0_eq,aaStmwB1 ; Error, bail...
647 stw r9,28(r16) ; Store word 7
649 addi r16,r16,8*4 ; Point up to next output aread
652 aaStmwB1: mr r4,r0 ; Remember DAR, jus in case we failed the access
653 mtmsr r30 ; Normal MSR
656 bt- cr0_eq,aaStmwNxt ; We have more to do and no failed access...
657 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
661 aaStmwNxtH: cmplwi cr1,r17,(4*4) ; Do we have at least 4 left?
662 blt cr1,aaStmwL4 ; Nope...
663 subi r17,r17,4*4 ; Set count properly
665 lwzx r2,r19,r18 ; Store register
666 addi r18,r18,8 ; Next register
667 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
668 lwzx r15,r19,r18 ; Store register
669 addi r18,r18,8 ; Next register
670 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
671 lwzx r14,r19,r18 ; Store register
672 addi r18,r18,8 ; Next register
673 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
674 lwzx r5,r19,r18 ; Store register
675 addi r18,r18,8 ; Next register
676 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
678 crset cr0_eq ; Set this to see if we failed
679 mtmsr r22 ; Flip DR, RI
682 stw r2,0(r16) ; Store word 0
683 bf- cr0_eq,aaStmwB2 ; Error, bail...
684 stw r15,4(r16) ; Store word 1
685 bf- cr0_eq,aaStmwB2 ; Error, bail...
686 stw r14,8(r16) ; Store word 2
687 bf- cr0_eq,aaStmwB2 ; Error, bail...
688 stw r5,12(r16) ; Store word 3
690 addi r16,r16,4*4 ; Point up to next input aread
692 aaStmwB2: mr r4,r0 ; Remember DAR, jus in case we failed the access
693 mtmsr r30 ; Normal MSR
696 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
698 aaStmwL4: or. r5,r17,r28 ; Do we have anything left to do?
699 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three left?
700 cmplwi cr2,r17,0 ; Do we have no full words left?
701 beq aaComExit ; Nothing left...
703 beq- cr2,aaStmwBy1 ; No full words, check out bytes
705 lwzx r2,r19,r18 ; Store register
706 addi r18,r18,8 ; Next register
707 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
708 blt cr1,aaStmwBy1 ; We only had one, go save it...
710 lwzx r15,r19,r18 ; Store register
711 addi r18,r18,8 ; Next register
712 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
713 beq cr1,aaStmwBy1 ; We had two, go save it...
715 lwzx r14,r19,r18 ; Store register
716 addi r18,r18,8 ; Next register
717 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
719 aaStmwBy1: mr. r28,r28 ; Do we have any trailing bytes?
720 beq+ aaStmwSt ; Nope...
722 lwzx r5,r19,r18 ; Yes, pick up one extra register
724 aaStmwSt: crset cr0_eq ; Set this to see if we failed
725 mtmsr r22 ; Flip DR, RI
728 beq- cr2,aaStmwBy2 ; No words, check trailing bytes...
730 stw r2,0(r16) ; Save first word
731 bf- cr0_eq,aaStmwDn ; Store failed, escape...
732 addi r16,r16,4 ; Bump sink
733 blt cr1,aaStmwBy2 ; We only had one, we are done...
735 stw r15,0(r16) ; Save second word
736 bf- cr0_eq,aaStmwDn ; Store failed, escape...
737 addi r16,r16,4 ; Bump sink
738 beq cr1,aaStmwBy2 ; We had two, we are done...
740 stw r14,0(r16) ; Save third word
741 bf- cr0_eq,aaStmwDn ; Store failed, escape...
742 addi r16,r16,4 ; Bump sink
744 aaStmwBy2: rlwinm r2,r5,8,24,31 ; Get byte 0
745 cmplwi cr2,r28,0 ; Any trailing bytes to do?
746 rlwinm r14,r5,24,24,31 ; Get byte 3
747 li r8,0 ; Clear second trailing byte
748 cmplwi cr1,r28,2 ; Check for 1, 2, or 3
749 li r9,0 ; Clear third trailing byte
750 beq+ cr2,aaStmwDn ; No trailing bytes...
751 rlwinm r15,r5,16,24,31 ; Get byte 1
753 stb r2,0(r16) ; Save first byte
754 bf- cr0_eq,aaStmwDn ; Read failed, escape...
755 blt cr1,aaStmwDn ; We only had one, we are done...
757 stb r15,1(r16) ; Save second byte
758 bf- cr0_eq,aaStmwDn ; Read failed, escape...
759 beq cr1,aaStmwDn ; We had two, we are done...
761 stb r14,2(r16) ; Save third byte
763 aaStmwDn: mr r4,r0 ; Remember DAR, jus in case we failed the access
764 mtmsr r30 ; Normal MSR
767 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
769 b aaComExit ; We are done....
773 ; Load String Indexed
778 aaLswx: lwz r17,savexer+4(r13) ; Pick up the XER
779 crclr iUpdate ; Make sure we think this the load form
780 rlwinm. r25,r17,0,25,31 ; Get the number of bytes to load
781 rlwinm r28,r17,0,30,31 ; Get the number of bytes past an even word
782 beq- aaComExit ; Do nothing if 0 length...
783 xor r17,r25,r28 ; Round down to an even word boundary
784 b aaLSComm ; Join up with common load/store code...
788 ; Load String Immediate
793 aaLswi: mr r9,r23 ; Save the DAR
794 bl eIFetch ; Get the instruction image
795 bne- eRedriveAsISI ; Go redrive this as an ISI...
796 rlwinm r25,r10,21,27,31 ; Get the number of bytes to load
797 crclr iUpdate ; Make sure we think this the load form
798 subi r25,r25,1 ; Back off by 1
799 rlwinm r25,r25,0,27,31 ; Clear back down
800 addi r25,r25,1 ; Add back the 1 to convert 0 to 32
801 rlwinm r28,r25,0,30,31 ; Get the number of bytes past an even word
802 xor r17,r25,r28 ; Round down to an even word boundary
803 mr r23,r9 ; Move back the DAR
804 b aaLSComm ; Join up with common load/store code...
807 ; Store String Indexed
812 aaStswx: lwz r17,savexer+4(r13) ; Pick up the XER
813 crclr iUpdate ; Make sure this is clear in case we have 0 length
814 rlwinm. r25,r17,0,25,31 ; Get the number of bytes to load
815 rlwinm r28,r17,0,30,31 ; Get the number of bytes past an even word
816 beq- aaComExit ; Do nothing if 0 length...
817 xor r17,r25,r28 ; Round down to an even word boundary
818 crset iUpdate ; Make sure we think this the store form
819 b aaLSComm ; Join up with common load/store code...
823 ; Store String Immediate
828 aaStswi: mr r9,r23 ; Save the DAR
829 bl eIFetch ; Get the instruction image
830 bne- eRedriveAsISI ; Go redrive this as an ISI...
831 rlwinm r25,r10,21,27,31 ; Get the number of bytes to load
832 crclr iUpdate ; Make sure we think this the load form
833 subi r25,r25,1 ; Back off by 1
834 rlwinm r25,r25,0,27,31 ; Clear back down
835 addi r25,r25,1 ; Add back the 1 to convert 0 to 32
836 rlwinm r28,r25,21,30,31 ; Get the number of bytes past an even word
837 xor r17,r25,r28 ; Round down to an even word boundary
838 mr r23,r9 ; Move back the DAR
839 b aaLSComm ; Join up with common load/store code...
843 ; Load byte-reversed word
849 add r18,r18,r13 ; Index to source register
851 crset cr0_eq ; Set this to see if we failed
852 mtmsr r22 ; Flip DR, RI, and maybe PR on
855 lwz r11,0(r23) ; Load the word
857 mr r4,r0 ; Save the DAR if we failed the access
858 mtmsr r30 ; Restore normal MSR
861 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
863 rlwinm r10,r11,8,0,31 ; Get byte 0 to 3 and byte 2 to 1
864 rlwimi r10,r11,24,16,23 ; Move byte 1 to byte 2
865 rlwimi r10,r11,24,0,7 ; Move byte 3 to byte 0
867 stw r10,saver0+4(r18) ; Set the register
869 b aaComExit ; All done, go exit...
874 ; Store byte-reversed word
880 add r18,r18,r13 ; Index to source register
881 lwz r11,saver0+4(r18) ; Get the register to store
883 rlwinm r10,r11,8,0,31 ; Get byte 0 to 3 and byte 2 to 1
884 rlwimi r10,r11,24,16,23 ; Move byte 1 to byte 2
885 rlwimi r10,r11,24,0,7 ; Move byte 3 to byte 0
887 crset cr0_eq ; Set this to see if we failed
888 mtmsr r22 ; Flip DR, RI, and maybe PR on
891 stw r10,0(r23) ; Store the reversed halfword
893 mr r4,r0 ; Save the DAR if we failed the access
894 mtmsr r30 ; Restore normal MSR
897 bt+ cr0_eq,aaComExit ; All done, go exit...
898 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
903 ; Load byte-reversed halfword
909 add r18,r18,r13 ; Index to source register
911 crset cr0_eq ; Set this to see if we failed
912 mtmsr r22 ; Flip DR, RI, and maybe PR on
915 lhz r11,0(r23) ; Load the halfword
917 mr r4,r0 ; Save the DAR if we failed the access
918 mtmsr r30 ; Restore normal MSR
921 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
923 rlwinm r10,r11,8,16,23 ; Rotate bottom byte up one and clear everything else
924 rlwimi r10,r11,24,24,31 ; Put old second from bottom into bottom
926 stw r10,saver0+4(r18) ; Set the register
928 b aaComExit ; All done, go exit...
932 ; Store byte-reversed halfword
938 add r18,r18,r13 ; Index to source register
939 lwz r10,saver0+4(r18) ; Get the register to store
940 rlwinm r10,r10,8,0,31 ; Rotate bottom byte up one
941 rlwimi r10,r10,16,24,31 ; Put old second from bottom into bottom
943 crset cr0_eq ; Set this to see if we failed
944 mtmsr r22 ; Flip DR, RI, and maybe PR on
947 sth r10,0(r23) ; Store the reversed halfword
949 mr r4,r0 ; Save the DAR if we failed the access
950 mtmsr r30 ; Restore normal MSR
953 bt+ cr0_eq,aaComExit ; All done, go exit...
954 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
957 ; Data cache block zero
963 lwz r0,savesrr0+4(r13) ; get instruction address
964 li r4,_COMM_PAGE_BASE_ADDRESS
965 rlwinm r23,r23,0,0,26 ; Round EA back to a 32-byte boundary
966 sub r4,r0,r4 ; compute instruction offset from base of commpage
967 cmplwi r4,_COMM_PAGE_AREA_USED ; did fault occur in commpage?
968 bge+ aaDcbz1 ; skip if not in commpage
969 lwz r4,savecr(r13) ; if we take a dcbz in the commpage...
970 rlwinm r4,r4,0,0,27 ; ...clear users cr7 as a flag for commpage code
973 crset cr0_eq ; Set this to see if we failed
974 li r0,0 ; Clear this out
975 mtmsr r22 ; Flip DR, RI, and maybe PR on
978 stw r0,0(r23) ; Clear word
979 bne- aaDcbzXit ; Got DSI, we are stopping...
980 stw r0,4(r23) ; Clear word
981 bne- aaDcbzXit ; Got DSI, we are stopping...
982 stw r0,8(r23) ; Clear word
983 bne- aaDcbzXit ; Got DSI, we are stopping...
984 stw r0,12(r23) ; Clear word
985 bne- aaDcbzXit ; Got DSI, we are stopping...
986 stw r0,16(r23) ; Clear word
987 bne- aaDcbzXit ; Got DSI, we are stopping...
988 stw r0,20(r23) ; Clear word
989 bne- aaDcbzXit ; Got DSI, we are stopping...
990 stw r0,24(r23) ; Clear word
991 bne- aaDcbzXit ; Got DSI, we are stopping...
992 stw r0,28(r23) ; Clear word
994 aaDcbzXit: mr r4,r0 ; Save the DAR if we failed the access
995 mtmsr r30 ; Restore normal MSR
998 crclr iUpdate ; Make sure we do not think this is an update form
1000 bt+ cr0_eq,aaComExit ; All done, go exit...
1001 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
1005 ; Unhandled alignment exception, pass it along
1009 li r0,1 ; Indicate that we failed to emulate
1010 stw r0,savemisc3(r13) ; Assume that we emulate ok
1017 ; We go here to emulate a trace exception after we have handled alignment error
1023 oris r9,r9,hi16(SAVredrive) ; Set the redrive bit
1024 li r11,T_TRACE ; Set trace interrupt
1025 rlwinm r12,r12,0,16,31 ; Clear top half of SRR1
1026 stw r9,SAVflags(r13) ; Set the flags
1027 stw r11,saveexception(r13) ; Set the exception code
1028 b EXT(EmulExit) ; Exit and do trace interrupt...
1036 mr r20,r1 ; Save the DSISR
1038 lwz r4,SAVflags(r13) ; Pick up the flags
1039 li r11,T_DATA_ACCESS ; Set failing data access code
1040 oris r4,r4,hi16(SAVredrive) ; Set the redrive bit
1041 stw r20,savedsisr(r13) ; Set the DSISR of failed access
1042 stw r21,savedar+4(r13) ; Set the address of the failed access
1043 stw r11,saveexception(r13) ; Set the replacement code
1044 stw r4,SAVflags(r13) ; Set redrive request
1045 b EXT(EmulExit) ; Bail out to handle ISI...
1050 ; Table of functions to load or store floating point registers
1051 ; This table is indexed reg||size||dir. That means that each
1052 ; like load/store pair (e.g., lfd f31/stfd f31) are within the same
1053 ; quadword, which is the current ifetch size. We expect most of the
1054 ; unaligned accesses to be part of copies, therefore, with this
1055 ; organization, we will save the ifetch of the store after the load.
1058 .align 10 ; Make sure we are on a 1k boundary
1059 .globl EXT(aaFPopTable)
1062 lfs f0,emfp0(r31) ; Load single variant
1065 stfs f0,emfp0(r31) ; Store single variant
1068 lfd f0,emfp0(r31) ; Load double variant
1071 stfd f0,emfp0(r31) ; Store double variant
1074 lfs f1,emfp0(r31) ; Load single variant
1077 stfs f1,emfp0(r31) ; Store single variant
1080 lfd f1,emfp0(r31) ; Load double variant
1083 stfd f1,emfp0(r31) ; Store double variant
1086 lfs f2,emfp0(r31) ; Load single variant
1089 stfs f2,emfp0(r31) ; Store single variant
1092 lfd f2,emfp0(r31) ; Load double variant
1095 stfd f2,emfp0(r31) ; Store double variant
1098 lfs f3,emfp0(r31) ; Load single variant
1101 stfs f3,emfp0(r31) ; Store single variant
1104 lfd f3,emfp0(r31) ; Load double variant
1107 stfd f3,emfp0(r31) ; Store double variant
1110 lfs f4,emfp0(r31) ; Load single variant
1113 stfs f4,emfp0(r31) ; Store single variant
1116 lfd f4,emfp0(r31) ; Load double variant
1119 stfd f4,emfp0(r31) ; Store double variant
1122 lfs f5,emfp0(r31) ; Load single variant
1125 stfs f5,emfp0(r31) ; Store single variant
1128 lfd f5,emfp0(r31) ; Load double variant
1131 stfd f5,emfp0(r31) ; Store double variant
1134 lfs f6,emfp0(r31) ; Load single variant
1137 stfs f6,emfp0(r31) ; Store single variant
1140 lfd f6,emfp0(r31) ; Load double variant
1143 stfd f6,emfp0(r31) ; Store double variant
1146 lfs f7,emfp0(r31) ; Load single variant
1149 stfs f7,emfp0(r31) ; Store single variant
1152 lfd f7,emfp0(r31) ; Load double variant
1155 stfd f7,emfp0(r31) ; Store double variant
1158 lfs f8,emfp0(r31) ; Load single variant
1161 stfs f8,emfp0(r31) ; Store single variant
1164 lfd f8,emfp0(r31) ; Load double variant
1167 stfd f8,emfp0(r31) ; Store double variant
1170 lfs f9,emfp0(r31) ; Load single variant
1173 stfs f9,emfp0(r31) ; Store single variant
1176 lfd f9,emfp0(r31) ; Load double variant
1179 stfd f9,emfp0(r31) ; Store double variant
1182 lfs f10,emfp0(r31) ; Load single variant
1185 stfs f10,emfp0(r31) ; Store single variant
1188 lfd f10,emfp0(r31) ; Load double variant
1191 stfd f10,emfp0(r31) ; Store double variant
1194 lfs f11,emfp0(r31) ; Load single variant
1197 stfs f11,emfp0(r31) ; Store single variant
1200 lfd f11,emfp0(r31) ; Load double variant
1203 stfd f11,emfp0(r31) ; Store double variant
1206 lfs f12,emfp0(r31) ; Load single variant
1209 stfs f12,emfp0(r31) ; Store single variant
1212 lfd f12,emfp0(r31) ; Load double variant
1215 stfd f12,emfp0(r31) ; Store double variant
1218 lfs f13,emfp0(r31) ; Load single variant
1221 stfs f13,emfp0(r31) ; Store single variant
1224 lfd f13,emfp0(r31) ; Load double variant
1227 stfd f13,emfp0(r31) ; Store double variant
1230 lfs f14,emfp0(r31) ; Load single variant
1233 stfs f14,emfp0(r31) ; Store single variant
1236 lfd f14,emfp0(r31) ; Load double variant
1239 stfd f14,emfp0(r31) ; Store double variant
1242 lfs f15,emfp0(r31) ; Load single variant
1245 stfs f15,emfp0(r31) ; Store single variant
1248 lfd f15,emfp0(r31) ; Load double variant
1251 stfd f15,emfp0(r31) ; Store double variant
1254 lfs f16,emfp0(r31) ; Load single variant
1257 stfs f16,emfp0(r31) ; Store single variant
1260 lfd f16,emfp0(r31) ; Load double variant
1263 stfd f16,emfp0(r31) ; Store double variant
1266 lfs f17,emfp0(r31) ; Load single variant
1269 stfs f17,emfp0(r31) ; Store single variant
1272 lfd f17,emfp0(r31) ; Load double variant
1275 stfd f17,emfp0(r31) ; Store double variant
1278 lfs f18,emfp0(r31) ; Load single variant
1281 stfs f18,emfp0(r31) ; Store single variant
1284 lfd f18,emfp0(r31) ; Load double variant
1287 stfd f18,emfp0(r31) ; Store double variant
1290 lfs f19,emfp0(r31) ; Load single variant
1293 stfs f19,emfp0(r31) ; Store single variant
1296 lfd f19,emfp0(r31) ; Load double variant
1299 stfd f19,emfp0(r31) ; Store double variant
1302 lfs f20,emfp0(r31) ; Load single variant
1305 stfs f20,emfp0(r31) ; Store single variant
1308 lfd f20,emfp0(r31) ; Load double variant
1311 stfd f20,emfp0(r31) ; Store double variant
1314 lfs f21,emfp0(r31) ; Load single variant
1317 stfs f21,emfp0(r31) ; Store single variant
1320 lfd f21,emfp0(r31) ; Load double variant
1323 stfd f21,emfp0(r31) ; Store double variant
1326 lfs f22,emfp0(r31) ; Load single variant
1329 stfs f22,emfp0(r31) ; Store single variant
1332 lfd f22,emfp0(r31) ; Load double variant
1335 stfd f22,emfp0(r31) ; Store double variant
1338 lfs f23,emfp0(r31) ; Load single variant
1341 stfs f23,emfp0(r31) ; Store single variant
1344 lfd f23,emfp0(r31) ; Load double variant
1347 stfd f23,emfp0(r31) ; Store double variant
1350 lfs f24,emfp0(r31) ; Load single variant
1353 stfs f24,emfp0(r31) ; Store single variant
1356 lfd f24,emfp0(r31) ; Load double variant
1359 stfd f24,emfp0(r31) ; Store double variant
1362 lfs f25,emfp0(r31) ; Load single variant
1365 stfs f25,emfp0(r31) ; Store single variant
1368 lfd f25,emfp0(r31) ; Load double variant
1371 stfd f25,emfp0(r31) ; Store double variant
1374 lfs f26,emfp0(r31) ; Load single variant
1377 stfs f26,emfp0(r31) ; Store single variant
1380 lfd f26,emfp0(r31) ; Load double variant
1383 stfd f26,emfp0(r31) ; Store double variant
1386 lfs f27,emfp0(r31) ; Load single variant
1389 stfs f27,emfp0(r31) ; Store single variant
1392 lfd f27,emfp0(r31) ; Load double variant
1395 stfd f27,emfp0(r31) ; Store double variant
1398 lfs f28,emfp0(r31) ; Load single variant
1401 stfs f28,emfp0(r31) ; Store single variant
1404 lfd f28,emfp0(r31) ; Load double variant
1407 stfd f28,emfp0(r31) ; Store double variant
1410 lfs f29,emfp0(r31) ; Load single variant
1413 stfs f29,emfp0(r31) ; Store single variant
1416 lfd f29,emfp0(r31) ; Load double variant
1419 stfd f29,emfp0(r31) ; Store double variant
1422 lfs f30,emfp0(r31) ; Load single variant
1425 stfs f30,emfp0(r31) ; Store single variant
1428 lfd f30,emfp0(r31) ; Load double variant
1431 stfd f30,emfp0(r31) ; Store double variant
1434 lfs f31,emfp0(r31) ; Load single variant
1437 stfs f31,emfp0(r31) ; Store single variant
1440 lfd f31,emfp0(r31) ; Load double variant
1443 stfd f31,emfp0(r31) ; Store double variant