2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_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. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
26 Emulate instructions and traps.
28 Lovingly crafted by Bill Angell using traditional methods and only natural or recycled materials.
29 No animal products are used other than rendered otter bile and deep fried pork lard.
34 #include <ppc/proc_reg.h>
35 #include <ppc/exception.h>
36 #include <ppc/cpu_capabilities.h>
37 #include <mach/machine/vm_param.h>
43 ; General stuff what happens here:
44 ; 1) All general context saved, interrupts off, translation off
45 ; 2) Vector and floating point disabled, but there may be live context.
46 ; This code is responsible for saving and restoring what is used. This
47 ; includes exception states, java mode, etc.
48 ; 3) No attempt is made to resolve page faults. PTE misses are handled
49 ; automatically, but actual faults (ala copyin/copyout) are not. If
50 ; a fault does occur, the exception that caused entry to the emulation
51 ; routine is remapped to either an instruction or data miss (depending
52 ; upon the stage detected) and redrived through the exception handler.
53 ; The only time that an instruction fault can happen is when a different
54 ; processor removes a mapping between our original fault and when we
55 ; fetch the assisted instruction. For an assisted instruction, data
56 ; faults should not occur (except in the MP case). For a purely
57 ; emulated instruction, faults can occur.
67 bf-- pf64Bitb,emn64 ; Skip if not 64-bit
68 b EXT(Emulate64) ; Jump to the 64-bit code...
70 emn64: mfsprg r31,0 ; Get the per_proc
71 lwz r12,savesrr1+4(r13) ; Get the exception info
72 rlwinm. r0,r12,0,SRR1_PRG_ILL_INS_BIT,SRR1_PRG_ILL_INS_BIT ; Emulation candidate?
73 lwz r30,dgFlags(0) ; Get the flags
74 beq+ eExit ; Nope, do not try to emulate...
76 rlwinm. r0,r30,0,enaDiagEMb,enaDiagEMb ; Do we want to try to emulate something?
77 mfsprg r28,2 ; Get the processor features
78 beq+ eExit ; No emulation allowed...
80 rlwinm. r28,r28,0,pfAltivecb,pfAltivecb ; Do we have Altivec on this machine?
81 beq eNoVect ; Nope, no Altivec...
83 dssall ; We need to kill streams because we are going to flip to problem state
86 eNoVect: bl eIFetch ; Get the instruction image
87 bne- eRedriveAsISI ; Go redrive this as an ISI...
89 rlwinm. r0,r10,0,0,5 ; See if we have the "special" op code here
90 rlwinm r20,r10,16,22,31 ; Set rS/rD and rA
91 bne+ eExit ; Not special op, ignore...
93 rlwinm r0,r10,31,22,31 ; Extract the sub op code
95 rlwimi r20,r10,14,15,16 ; Move bits 29 and 30 of instruction to 15 and 16 of DSISR
96 cmplwi r0,790 ; lhbrx?
97 rlwimi r20,r10,8,17,17 ; Move bit 25 to bit 17
98 cror cr1_eq,cr1_eq,cr0_eq ; Remember
99 cmplwi r0,534 ; lwbrx?
100 rlwimi r20,r10,3,18,21 ; Move bit 21-24 to bit 18-21
101 cror cr1_eq,cr1_eq,cr0_eq ; Remember
102 cmplwi r0,918 ; sthbrx?
103 cror cr1_eq,cr1_eq,cr0_eq ; Remember
104 cmplwi r0,662 ; stwbrx?
105 cror cr1_eq,cr1_eq,cr0_eq ; Remember
106 cmplwi r0,1014 ; dcbz?
107 cror cr1_eq,cr1_eq,cr0_eq ; Remember
108 cmplwi r0,533 ; lswx?
109 cror cr1_eq,cr1_eq,cr0_eq ; Remember
110 cmplwi r0,661 ; stswx?
111 cror cr1_eq,cr1_eq,cr0_eq ; Remember
112 bne cr1_eq,eNotIndex ; Go check non-index forms...
114 rlwinm. r21,r10,19,24,28 ; Extract index to rA to build EA
115 rlwinm r22,r10,24,24,28 ; Extract index to rB
116 addi r24,r13,saver0+4 ; Point to the start of registers
117 li r19,0 ; Assume 0 base
118 beq eZeroBase ; Yes...
119 lwzx r19,r24,r21 ; Get the base register value
121 eZeroBase: lwzx r22,r24,r22 ; Get the index value
122 add r22,r22,r19 ; Get DAR
123 b eFinishUp ; Done, go finish up...
125 eNotIndex: cmplwi r0,725 ; stswi?
126 cror cr1_eq,cr1_eq,cr0_eq ; Remember
127 cmplwi r0,597 ; lswi?
128 cror cr1_eq,cr1_eq,cr0_eq ; Remember
129 bne cr1,eExit ; Not one we handle...
131 rlwinm. r21,r10,19,24,28 ; Extract index to rA to build EA
132 addi r24,r13,saver0+4 ; Point to the start of registers
133 li r22,0 ; Assume 0 base
134 beq eFinishUp ; Yes, it is...
135 lwzx r22,r24,r21 ; Get the base register value
137 eFinishUp: stw r20,savedsisr(r13) ; Set the DSISR
138 li r11,T_ALIGNMENT ; Get the exception code
139 stw r22,savedar+4(r13) ; Save the DAR
140 stw r11,saveexception(r13) ; Set the exception code
141 b EXT(AlignAssist) ; Go emulate the handler...
144 eExit: b EXT(EmulExit) ; Just return for now...
148 ; Fetch the failing instruction.
149 ; Image returned in R10 if CR0_EQ is false, otherwise, an ISI should be generated/
150 ; The cr bit kernAccess is set if this was a kernel access.
151 ; R1 has the DSISR if access failed.
156 eIFetch: lwz r23,savesrr1+4(r13) ; Get old MSR
157 mflr r28 ; Save return
159 rlwinm. r22,r23,0,MSR_PR_BIT,MSR_PR_BIT ; Within kernel?
161 mfmsr r30 ; Save the MSR for now
162 lwz r23,savesrr0+4(r13) ; Get instruction address
164 ori r22,r30,lo16(MASK(MSR_DR)|MASK(MSR_RI)) ; Set RI and DR onto access MSR
166 crset cr0_eq ; Set this to see if we failed
167 mtmsr r22 ; Flip DR, RI, and maybe PR on
170 lwz r10,0(r23) ; Fetch the instruction
172 mtmsr r30 ; Trans and RI off
175 mtlr r28 ; Restore the LR
176 blr ; Return with instruction image in R10
184 lwz r6,savesrr1+4(r13) ; Get the srr1 value
185 lwz r4,SAVflags(r13) ; Pick up the flags
186 li r11,T_INSTRUCTION_ACCESS ; Set failing instruction fetch code
187 rlwimi r6,r1,0,0,4 ; Move the DSISR bits to the SRR1
188 oris r4,r4,hi16(SAVredrive) ; Set the redrive bit
189 stw r11,saveexception(r13) ; Set the replacement code
190 stw r4,SAVflags(r13) ; Set redrive request
191 stw r6,savesrr1+4(r13) ; Set the srr1 value
192 b EXT(EmulExit) ; Bail out to handle ISI...
196 ; This code emulates instructions that have failed because of operand
197 ; alignment. We decode the DSISR to figure out what we need to do.
200 ; 0001FC00 - Instruction designation
210 ; 000003E0 - Target/Source register
211 ; 0000001F - Register to update if update form
215 .globl EXT(AlignAssist)
218 bf-- pf64Bitb,aan64 ; Skip if not 64-bit
219 b EXT(AlignAssist64) ; Jump to the 64-bit code...
221 aan64: lwz r20,savedsisr(r13) ; Get the DSISR
222 li r0,0 ; Assume we emulate
223 mfsprg r31,0 ; Get the per_proc
224 mtcrf 0x10,r20 ; Put instruction ID in CR for later
225 lwz r21,spcFlags(r31) ; Grab the special flags
226 stw r0,savemisc3(r13) ; Assume that we emulate ok
227 mtcrf 0x08,r20 ; Put instruction ID in CR for later
228 rlwinm. r0,r21,0,runningVMbit,runningVMbit ; Are we running a VM?
229 mtcrf 0x04,r20 ; Put instruction ID in CR for later
230 lwz r22,savesrr1+4(r13) ; Get the SRR1
231 bne- aaPassAlong ; We are in a VM, no emulation for alignment exceptions...
232 lwz r19,dgFlags(0) ; Get the diagnostics flags
233 crxor iFloat,iOptype1,iOptype2 ; Set this to 0 if both bits are either 0 or 1
234 mr r26,r20 ; Save the DSISR
235 rlwinm. r0,r22,0,MSR_SE_BIT,MSR_SE_BIT ; Were we single stepping?
236 lwz r23,savedar+4(r13) ; Pick up the address that we want to access
237 crnot traceInst,cr0_eq ; Remember if trace is on
239 rlwinm. r0,r19,0,enaNotifyEMb,enaNotifyEMb ; Should we notify that an alignment exception happened?
240 mfmsr r30 ; Save the MSR for now
241 crnot iNotify,cr0_eq ; Remember to tell someone we did this
242 li r29,emfp0 ; Point to work area
243 crxor iFloat,iFloat,iOptype3 ; Set true if we have a floating point instruction
244 dcbz r29,r31 ; Clear and allocate a cache line for us to work in
245 rlwinm r24,r20,3,24,28 ; Get displacement to register to update if update form
246 rlwimi r20,r20,24,28,28 ; Move load/store indication to the bottom of index
247 ori r22,r30,lo16(MASK(MSR_DR)|MASK(MSR_RI)) ; Set RI onto access MSR
248 rlwimi r20,r20,26,27,27 ; Move single/double indication to just above the bottom
249 lis r29,hi16(EXT(aaFPopTable)) ; High part of FP branch table
250 bf- iFloat,aaNotFloat ; This is not a floating point instruction...
251 ori r29,r29,lo16(EXT(aaFPopTable)) ; Low part of FP branch table
253 rlwimi r29,r20,0,22,28 ; Index into table based upon register||iDouble||iStore
254 mtctr r29 ; Get set to call the function
255 bt iStore,aaFPstore ; This is an FP store...
258 ; Here we handle floating point loads
261 aaFPload: crset cr0_eq ; Set this to see if we failed
262 mtmsr r22 ; Flip DR, RI
265 lwz r10,0(r23) ; Get the first word
266 bf- cr0_eq,aaLdNotDbl ; Jump out if we DSIed...
267 bf iDouble,aaLdNotDbl ; this is not a double...
268 lwz r11,4(r23) ; Get the second half
270 aaLdNotDbl: mr r4,r0 ; Save the DAR if we failed the access
272 mtmsr r30 ; Turn off translation again
275 bf- cr0_eq,aaRedriveAsDSI ; Go redrive this as a DSI...
277 stw r10,emfp0(r31) ; Save the first half
278 stw r11,emfp0+4(r31) ; Save the second half, just in case we need it
280 bctrl ; Go set the target FP register
282 b aaComExit ; All done, go exit...
285 ; Here we handle floating point stores
290 aaFPstore: bctrl ; Go save the source FP register
292 lwz r10,emfp0(r31) ; Get first word
293 crandc iDouble,iDouble,iOptype4 ; Change to 4-byte access if stfiwx
294 lwz r11,emfp0+4(r31) ; and the second
295 bf+ iOptype4,aaNotstfiwx ; This is not a stfiwx...
296 mr r10,r11 ; The stfiwx wants to store the second half
299 crset cr0_eq ; Set this to see if we failed
300 mtmsr r22 ; Flip DR, RI
303 stw r10,0(r23) ; Save the first word
304 bf- cr0_eq,aaStNotDbl ; Jump out if we DSIed...
305 bf iDouble,aaStNotDbl ; this is not a double...
306 stw r11,4(r23) ; Save the second half
308 aaStNotDbl: mr r4,r0 ; Save the DAR if we failed the access
312 bf- cr0_eq,aaRedriveAsDSI ; Go redrive this as a DSI...
315 ; Common exit routines
318 aaComExit: lwz r10,savesrr0+4(r13) ; Get the failing instruction address
319 add r24,r24,r13 ; Offset to update register
320 li r11,T_IN_VAIN ; Assume we are all done
321 addi r10,r10,4 ; Step to the next instruction
322 bf iUpdate,aaComExNU ; Skip if not an update form...
323 stw r23,saver0+4(r24) ; Update the target
325 aaComExNU: lwz r9,SAVflags(r13) ; Get the flags
326 stw r10,savesrr0+4(r13) ; Set new PC
327 bt- traceInst,aaComExitrd ; We are tracing, go emulate trace...
328 bf+ iNotify,aaComExGo ; Nothing special here, go...
330 li r11,T_ALIGNMENT ; Set the we just did an alignment exception....
332 aaComExGo: b EXT(EmulExit) ; We are done, no tracing on...
336 ; This is not a floating point operation
338 ; The table of these emulation routines is indexed by taking the low order 4 bits of
339 ; the instruction code in the DSISR and subtracting 7. If this comes up negative,
340 ; the instruction is not to be emulated. Then we add bit 0 of the code * 4. This
341 ; gives us a fairly compact and almost unique index. Both lwm and stmw map to 0 so
342 ; that one needs to be further reduced, and we end up with holes at a few indexes.
348 lis r19,hi16(aaEmTable) ; Point to high part of table address
349 rlwinm r3,r26,24,26,29 ; Isolate last 4 bits of op type * 4
350 rlwimi r19,r26,20,27,27 ; Get bit 0 of instruction code * 4 into bottom of table base
351 addic. r3,r3,-28 ; Subtract 7*4 to adjust index
352 ori r19,r19,lo16(aaEmTable) ; Low part of table address
353 blt- aaPassAlong ; We do not handle any of these (lwarx, stwcx., eciwx, ecowx)...
354 add r19,r19,r3 ; Point to emulation routine
355 rlwinm r18,r26,30,24,28 ; Get the target/source register displacement
357 mtctr r19 ; Set the routine address
359 bctr ; Go emulate the instruction...
362 ; This is the table of non-floating point emulation routines.
363 ; It is indexed by the code immediately above.
368 b aaLmwStmw ; This for lmw/stmw
369 b aaLswx ; This for lwwx
370 b aaLswi ; This for lswi
371 b aaStswx ; This for stswx
372 b aaStswi ; This for stswi
373 b aaLwbrx ; This for lwbrx
374 b aaPassAlong ; This an invalid index (6)
375 b aaStwbrx ; This for stwbrx
376 b aaPassAlong ; This an invalid index (8)
377 b aaLhbrx ; This for lhbrx
378 b aaPassAlong ; This an invalid index (A)
379 b aaSthbrx ; This for sthbrx
380 b aaDcbz ; This for dcbz
381 b aaPassAlong ; This an invalid index (D)
382 b aaPassAlong ; This an invalid index (E)
383 b aaPassAlong ; This an invalid index (F)
387 ; Here we handle the set up for the lmw and stmw. After that, we split off to the
388 ; individual routines.
390 ; Note also that after some set up, all of the string instructions come through here as well.
395 rlwinm r17,r18,31,1,29 ; Convert doublword based index to words
396 li r28,0 ; Set no extra bytes to move (used for string instructions)
397 subfic r17,r17,32*4 ; Calculate the length of the transfer
399 aaLSComm: addi r19,r13,saver0+4 ; Offset to registers in savearea
400 mr r16,r23 ; Make a hunk pointer
402 bt iUpdate,aaStmw ; This is the stmw...
408 aaLmwNxt: cmplwi cr1,r17,8*4 ; Is there enough to move 8?
409 blt- cr1,aaLmwNxtH ; Not enough for a full hunk...
410 subi r17,r17,8*4 ; Back off for another hunk
412 crset cr0_eq ; Set this to see if we failed
413 mtmsr r22 ; Flip DR, RI
416 lwz r2,0(r16) ; Load word 0
417 bf- cr0_eq,aaLmwB1 ; Error, bail...
418 lwz r15,4(r16) ; Load word 1
419 bf- cr0_eq,aaLmwB1 ; Error, bail...
420 lwz r14,8(r16) ; Load word 2
421 bf- cr0_eq,aaLmwB1 ; Error, bail...
422 lwz r5,12(r16) ; Load word 3
423 bf- cr0_eq,aaLmwB1 ; Error, bail...
424 lwz r6,16(r16) ; Load word 4
425 bf- cr0_eq,aaLmwB1 ; Error, bail...
426 lwz r7,20(r16) ; Load word 5
427 bf- cr0_eq,aaLmwB1 ; Error, bail...
428 lwz r8,24(r16) ; Load word 6
429 bf- cr0_eq,aaLmwB1 ; Error, bail...
430 lwz r9,28(r16) ; Load word 7
432 aaLmwB1: mr r4,r0 ; Remember DAR, jus in case we failed the access
433 mtmsr r30 ; Turn off DR, RI
436 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
438 addi r16,r16,8*4 ; Point up to next input aread
440 stwx r2,r19,r18 ; Store register
441 addi r18,r18,8 ; Next register
442 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
443 stwx r15,r19,r18 ; Store register
444 addi r18,r18,8 ; Next register
445 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
446 stwx r14,r19,r18 ; Store register
447 addi r18,r18,8 ; Next register
448 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
449 stwx r5,r19,r18 ; Store register
450 addi r18,r18,8 ; Next register
451 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
452 stwx r6,r19,r18 ; Store register
453 addi r18,r18,8 ; Next register
454 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
455 stwx r7,r19,r18 ; Store register
456 addi r18,r18,8 ; Next register
457 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
458 stwx r8,r19,r18 ; Store register
459 addi r18,r18,8 ; Next register
460 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
461 stwx r9,r19,r18 ; Store register
462 addi r18,r18,8 ; Next register
463 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
465 b aaLmwNxt ; Do the next hunk...
469 aaLmwNxtH: cmplwi cr1,r17,4*4 ; Do we have 4 left?
470 blt cr1,aaLmwL4 ; Nope...
472 subi r17,r17,4*4 ; Set count properly
474 crset cr0_eq ; Set this to see if we failed
475 mtmsr r22 ; Flip DR, RI, and maybe PR on
478 lwz r2,0(r16) ; Load word 0
479 bf- cr0_eq,aaLmwB2 ; Error, bail...
480 lwz r15,4(r16) ; Load word 1
481 bf- cr0_eq,aaLmwB2 ; Error, bail...
482 lwz r14,8(r16) ; Load word 2
483 bf- cr0_eq,aaLmwB2 ; Error, bail...
484 lwz r5,12(r16) ; Load word 3
486 aaLmwB2: mr r4,r0 ; Remember DAR, jus in case we failed the access
487 mtmsr r30 ; Turn off DR, RI
490 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
492 addi r16,r16,4*4 ; Point up to next input aread
494 stwx r2,r19,r18 ; Store register
495 addi r18,r18,8 ; Next register
496 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
497 stwx r15,r19,r18 ; Store register
498 addi r18,r18,8 ; Next register
499 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
500 stwx r14,r19,r18 ; Store register
501 addi r18,r18,8 ; Next register
502 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
503 stwx r5,r19,r18 ; Store register
504 addi r18,r18,8 ; Next register
505 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
507 aaLmwL4: or. r5,r17,r28 ; Do we have anything left?
508 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three full words left?
509 cmplwi cr2,r17,0 ; Do we have no full words left?
510 beq aaComExit ; Nothing left...
512 crset cr0_eq ; Set this to see if we failed
513 mtmsr r22 ; Flip DR, RI, and maybe PR on
516 beq- cr2,aaLmwBy ; No full words, get bytes...
518 lwz r2,0(r16) ; Pick up first word
519 bf- cr0_eq,aaLmwDn ; Read failed, escape...
520 addi r16,r16,4 ; Next input location
521 blt cr1,aaLmwBy ; We only had one, we are done...
523 lwz r15,0(r16) ; Pick up second word
524 bf- cr0_eq,aaLmwDn ; Read failed, escape...
525 addi r16,r16,4 ; Next input location
526 beq cr1,aaLmwBy ; We had two, we are done...
528 lwz r14,0(r16) ; Load word 3
529 addi r16,r16,4 ; Next input location
531 aaLmwBy: cmplwi cr2,r28,0 ; Any trailing bytes to do?
532 li r8,0 ; Clear second trailing byte
533 cmplwi cr1,r28,2 ; Check for 1, 2, or 3
534 li r9,0 ; Clear third trailing byte
535 beq+ cr2,aaLmwDn ; No trailing bytes...
537 lbz r5,0(r16) ; Pick up first trailing byte
538 bf- cr0_eq,aaLmwDn ; Read failed, escape...
539 blt cr1,aaLmwDn ; We only had one, we are done...
541 lbz r8,1(r16) ; Pick up second trailing byte
542 bf- cr0_eq,aaLmwDn ; Read failed, escape...
543 beq cr1,aaLmwDn ; We had two, we are done...
545 lbz r9,2(r16) ; Get last trailing byte
548 aaLmwDn: rlwinm r5,r5,24,0,7 ; Move first byte to top
549 cmplwi cr2,r17,0 ; Any full words to do?
550 mr r4,r0 ; Remember DAR, just in case we failed the access
551 rlwimi r9,r8,8,16,23 ; Move second byte above third byte
552 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three full words left?
553 mr r3,r30 ; Set the normal MSR
554 rlwimi r5,r9,8,8,23 ; Move bytes 1 and 2 after 0
556 mtmsr r30 ; Turn off DR, RI
559 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
561 beq- cr2,aaLmwCb ; No full words, copy bytes...
563 stwx r2,r19,r18 ; Store register
564 addi r18,r18,8 ; Next register
565 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
566 blt cr1,aaLmwCb ; We only had one, we are done...
568 stwx r15,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 beq cr1,aaLmwCb ; We had two, we are done...
573 stwx r14,r19,r18 ; Store register
574 addi r18,r18,8 ; Next register
575 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
577 aaLmwCb: mr. r28,r28 ; Any trailing bytes to do?
578 beq+ aaComExit ; Nope, leave...
580 stwx r5,r19,r18 ; Store register
582 b aaComExit ; We are done....
585 ; Store multiple word
591 crclr iUpdate ; Make sure we do not think this is an update form
593 aaStmwNxt: cmplwi cr1,r17,8*4 ; Is there enough to move 8?
594 blt- cr1,aaStmwNxtH ; Not enough for a full hunk...
595 subi r17,r17,8*4 ; Back off for another hunk
597 lwzx r2,r19,r18 ; Store register
598 addi r18,r18,8 ; Next register
599 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
600 lwzx r15,r19,r18 ; Store register
601 addi r18,r18,8 ; Next register
602 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
603 lwzx r14,r19,r18 ; Store register
604 addi r18,r18,8 ; Next register
605 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
606 lwzx r5,r19,r18 ; Store register
607 addi r18,r18,8 ; Next register
608 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
609 lwzx r6,r19,r18 ; Store register
610 addi r18,r18,8 ; Next register
611 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
612 lwzx r7,r19,r18 ; Store register
613 addi r18,r18,8 ; Next register
614 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
615 lwzx r8,r19,r18 ; Store register
616 addi r18,r18,8 ; Next register
617 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
618 lwzx r9,r19,r18 ; Store register
619 addi r18,r18,8 ; Next register
620 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
622 crset cr0_eq ; Set this to see if we failed
623 mtmsr r22 ; Flip DR, RI, and maybe PR on
626 stw r2,0(r16) ; Store word 0
627 bf- cr0_eq,aaStmwB1 ; Error, bail...
628 stw r15,4(r16) ; Store word 1
629 bf- cr0_eq,aaStmwB1 ; Error, bail...
630 stw r14,8(r16) ; Store word 2
631 bf- cr0_eq,aaStmwB1 ; Error, bail...
632 stw r5,12(r16) ; Store word 3
633 bf- cr0_eq,aaStmwB1 ; Error, bail...
634 stw r6,16(r16) ; Store word 4
635 bf- cr0_eq,aaStmwB1 ; Error, bail...
636 stw r7,20(r16) ; Store word 5
637 bf- cr0_eq,aaStmwB1 ; Error, bail...
638 stw r8,24(r16) ; Store word 6
639 bf- cr0_eq,aaStmwB1 ; Error, bail...
640 stw r9,28(r16) ; Store word 7
642 addi r16,r16,8*4 ; Point up to next output aread
645 aaStmwB1: mr r4,r0 ; Remember DAR, jus in case we failed the access
646 mtmsr r30 ; Normal MSR
649 bt- cr0_eq,aaStmwNxt ; We have more to do and no failed access...
650 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
654 aaStmwNxtH: cmplwi cr1,r17,(4*4) ; Do we have at least 4 left?
655 blt cr1,aaStmwL4 ; Nope...
656 subi r17,r17,4*4 ; Set count properly
658 lwzx r2,r19,r18 ; Store register
659 addi r18,r18,8 ; Next register
660 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
661 lwzx r15,r19,r18 ; Store register
662 addi r18,r18,8 ; Next register
663 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
664 lwzx r14,r19,r18 ; Store register
665 addi r18,r18,8 ; Next register
666 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
667 lwzx r5,r19,r18 ; Store register
668 addi r18,r18,8 ; Next register
669 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
671 crset cr0_eq ; Set this to see if we failed
672 mtmsr r22 ; Flip DR, RI
675 stw r2,0(r16) ; Store word 0
676 bf- cr0_eq,aaStmwB2 ; Error, bail...
677 stw r15,4(r16) ; Store word 1
678 bf- cr0_eq,aaStmwB2 ; Error, bail...
679 stw r14,8(r16) ; Store word 2
680 bf- cr0_eq,aaStmwB2 ; Error, bail...
681 stw r5,12(r16) ; Store word 3
683 addi r16,r16,4*4 ; Point up to next input aread
685 aaStmwB2: mr r4,r0 ; Remember DAR, jus in case we failed the access
686 mtmsr r30 ; Normal MSR
689 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
691 aaStmwL4: or. r5,r17,r28 ; Do we have anything left to do?
692 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three left?
693 cmplwi cr2,r17,0 ; Do we have no full words left?
694 beq aaComExit ; Nothing left...
696 beq- cr2,aaStmwBy1 ; No full words, check out bytes
698 lwzx r2,r19,r18 ; Store register
699 addi r18,r18,8 ; Next register
700 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
701 blt cr1,aaStmwBy1 ; We only had one, go save it...
703 lwzx r15,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 beq cr1,aaStmwBy1 ; We had two, go save it...
708 lwzx r14,r19,r18 ; Store register
709 addi r18,r18,8 ; Next register
710 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
712 aaStmwBy1: mr. r28,r28 ; Do we have any trailing bytes?
713 beq+ aaStmwSt ; Nope...
715 lwzx r5,r19,r18 ; Yes, pick up one extra register
717 aaStmwSt: crset cr0_eq ; Set this to see if we failed
718 mtmsr r22 ; Flip DR, RI
721 beq- cr2,aaStmwBy2 ; No words, check trailing bytes...
723 stw r2,0(r16) ; Save first word
724 bf- cr0_eq,aaStmwDn ; Store failed, escape...
725 addi r16,r16,4 ; Bump sink
726 blt cr1,aaStmwBy2 ; We only had one, we are done...
728 stw r15,0(r16) ; Save second word
729 bf- cr0_eq,aaStmwDn ; Store failed, escape...
730 addi r16,r16,4 ; Bump sink
731 beq cr1,aaStmwBy2 ; We had two, we are done...
733 stw r14,0(r16) ; Save third word
734 bf- cr0_eq,aaStmwDn ; Store failed, escape...
735 addi r16,r16,4 ; Bump sink
737 aaStmwBy2: rlwinm r2,r5,8,24,31 ; Get byte 0
738 cmplwi cr2,r28,0 ; Any trailing bytes to do?
739 rlwinm r14,r5,24,24,31 ; Get byte 3
740 li r8,0 ; Clear second trailing byte
741 cmplwi cr1,r28,2 ; Check for 1, 2, or 3
742 li r9,0 ; Clear third trailing byte
743 beq+ cr2,aaStmwDn ; No trailing bytes...
744 rlwinm r15,r5,16,24,31 ; Get byte 1
746 stb r2,0(r16) ; Save first byte
747 bf- cr0_eq,aaStmwDn ; Read failed, escape...
748 blt cr1,aaStmwDn ; We only had one, we are done...
750 stb r15,1(r16) ; Save second byte
751 bf- cr0_eq,aaStmwDn ; Read failed, escape...
752 beq cr1,aaStmwDn ; We had two, we are done...
754 stb r14,2(r16) ; Save third byte
756 aaStmwDn: mr r4,r0 ; Remember DAR, jus in case we failed the access
757 mtmsr r30 ; Normal MSR
760 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
762 b aaComExit ; We are done....
766 ; Load String Indexed
771 aaLswx: lwz r17,savexer+4(r13) ; Pick up the XER
772 crclr iUpdate ; Make sure we think this the load form
773 rlwinm. r25,r17,0,25,31 ; Get the number of bytes to load
774 rlwinm r28,r17,0,30,31 ; Get the number of bytes past an even word
775 beq- aaComExit ; Do nothing if 0 length...
776 xor r17,r25,r28 ; Round down to an even word boundary
777 b aaLSComm ; Join up with common load/store code...
781 ; Load String Immediate
786 aaLswi: mr r9,r23 ; Save the DAR
787 bl eIFetch ; Get the instruction image
788 bne- eRedriveAsISI ; Go redrive this as an ISI...
789 rlwinm r25,r10,21,27,31 ; Get the number of bytes to load
790 crclr iUpdate ; Make sure we think this the load form
791 subi r25,r25,1 ; Back off by 1
792 rlwinm r25,r25,0,27,31 ; Clear back down
793 addi r25,r25,1 ; Add back the 1 to convert 0 to 32
794 rlwinm r28,r25,0,30,31 ; Get the number of bytes past an even word
795 xor r17,r25,r28 ; Round down to an even word boundary
796 mr r23,r9 ; Move back the DAR
797 b aaLSComm ; Join up with common load/store code...
800 ; Store String Indexed
805 aaStswx: lwz r17,savexer+4(r13) ; Pick up the XER
806 crclr iUpdate ; Make sure this is clear in case we have 0 length
807 rlwinm. r25,r17,0,25,31 ; Get the number of bytes to load
808 rlwinm r28,r17,0,30,31 ; Get the number of bytes past an even word
809 beq- aaComExit ; Do nothing if 0 length...
810 xor r17,r25,r28 ; Round down to an even word boundary
811 crset iUpdate ; Make sure we think this the store form
812 b aaLSComm ; Join up with common load/store code...
816 ; Store String Immediate
821 aaStswi: mr r9,r23 ; Save the DAR
822 bl eIFetch ; Get the instruction image
823 bne- eRedriveAsISI ; Go redrive this as an ISI...
824 rlwinm r25,r10,21,27,31 ; Get the number of bytes to load
825 crclr iUpdate ; Make sure we think this the load form
826 subi r25,r25,1 ; Back off by 1
827 rlwinm r25,r25,0,27,31 ; Clear back down
828 addi r25,r25,1 ; Add back the 1 to convert 0 to 32
829 rlwinm r28,r25,21,30,31 ; Get the number of bytes past an even word
830 xor r17,r25,r28 ; Round down to an even word boundary
831 mr r23,r9 ; Move back the DAR
832 b aaLSComm ; Join up with common load/store code...
836 ; Load byte-reversed word
842 add r18,r18,r13 ; Index to source register
844 crset cr0_eq ; Set this to see if we failed
845 mtmsr r22 ; Flip DR, RI, and maybe PR on
848 lwz r11,0(r23) ; Load the word
850 mr r4,r0 ; Save the DAR if we failed the access
851 mtmsr r30 ; Restore normal MSR
854 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
856 rlwinm r10,r11,8,0,31 ; Get byte 0 to 3 and byte 2 to 1
857 rlwimi r10,r11,24,16,23 ; Move byte 1 to byte 2
858 rlwimi r10,r11,24,0,7 ; Move byte 3 to byte 0
860 stw r10,saver0+4(r18) ; Set the register
862 b aaComExit ; All done, go exit...
867 ; Store byte-reversed word
873 add r18,r18,r13 ; Index to source register
874 lwz r11,saver0+4(r18) ; Get the register to store
876 rlwinm r10,r11,8,0,31 ; Get byte 0 to 3 and byte 2 to 1
877 rlwimi r10,r11,24,16,23 ; Move byte 1 to byte 2
878 rlwimi r10,r11,24,0,7 ; Move byte 3 to byte 0
880 crset cr0_eq ; Set this to see if we failed
881 mtmsr r22 ; Flip DR, RI, and maybe PR on
884 stw r10,0(r23) ; Store the reversed halfword
886 mr r4,r0 ; Save the DAR if we failed the access
887 mtmsr r30 ; Restore normal MSR
890 bt+ cr0_eq,aaComExit ; All done, go exit...
891 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
896 ; Load byte-reversed halfword
902 add r18,r18,r13 ; Index to source register
904 crset cr0_eq ; Set this to see if we failed
905 mtmsr r22 ; Flip DR, RI, and maybe PR on
908 lhz r11,0(r23) ; Load the halfword
910 mr r4,r0 ; Save the DAR if we failed the access
911 mtmsr r30 ; Restore normal MSR
914 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
916 rlwinm r10,r11,8,16,23 ; Rotate bottom byte up one and clear everything else
917 rlwimi r10,r11,24,24,31 ; Put old second from bottom into bottom
919 stw r10,saver0+4(r18) ; Set the register
921 b aaComExit ; All done, go exit...
925 ; Store byte-reversed halfword
931 add r18,r18,r13 ; Index to source register
932 lwz r10,saver0+4(r18) ; Get the register to store
933 rlwinm r10,r10,8,0,31 ; Rotate bottom byte up one
934 rlwimi r10,r10,16,24,31 ; Put old second from bottom into bottom
936 crset cr0_eq ; Set this to see if we failed
937 mtmsr r22 ; Flip DR, RI, and maybe PR on
940 sth r10,0(r23) ; Store the reversed halfword
942 mr r4,r0 ; Save the DAR if we failed the access
943 mtmsr r30 ; Restore normal MSR
946 bt+ cr0_eq,aaComExit ; All done, go exit...
947 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
950 ; Data cache block zero
956 lwz r0,savesrr0+4(r13) ; get instruction address
957 li r4,_COMM_PAGE_BASE_ADDRESS
958 rlwinm r23,r23,0,0,26 ; Round EA back to a 32-byte boundary
959 sub r4,r0,r4 ; compute instruction offset from base of commpage
960 cmplwi r4,_COMM_PAGE_AREA_USED ; did fault occur in commpage?
961 bge+ aaDcbz1 ; skip if not in commpage
962 lwz r4,savecr(r13) ; if we take a dcbz in the commpage...
963 rlwinm r4,r4,0,0,27 ; ...clear users cr7 as a flag for commpage code
966 crset cr0_eq ; Set this to see if we failed
967 li r0,0 ; Clear this out
968 mtmsr r22 ; Flip DR, RI, and maybe PR on
971 stw r0,0(r23) ; Clear word
972 bne- aaDcbzXit ; Got DSI, we are stopping...
973 stw r0,4(r23) ; Clear word
974 bne- aaDcbzXit ; Got DSI, we are stopping...
975 stw r0,8(r23) ; Clear word
976 bne- aaDcbzXit ; Got DSI, we are stopping...
977 stw r0,12(r23) ; Clear word
978 bne- aaDcbzXit ; Got DSI, we are stopping...
979 stw r0,16(r23) ; Clear word
980 bne- aaDcbzXit ; Got DSI, we are stopping...
981 stw r0,20(r23) ; Clear word
982 bne- aaDcbzXit ; Got DSI, we are stopping...
983 stw r0,24(r23) ; Clear word
984 bne- aaDcbzXit ; Got DSI, we are stopping...
985 stw r0,28(r23) ; Clear word
987 aaDcbzXit: mr r4,r0 ; Save the DAR if we failed the access
988 mtmsr r30 ; Restore normal MSR
991 crclr iUpdate ; Make sure we do not think this is an update form
993 bt+ cr0_eq,aaComExit ; All done, go exit...
994 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
998 ; Unhandled alignment exception, pass it along
1002 li r0,1 ; Indicate that we failed to emulate
1003 stw r0,savemisc3(r13) ; Assume that we emulate ok
1010 ; We go here to emulate a trace exception after we have handled alignment error
1016 oris r9,r9,hi16(SAVredrive) ; Set the redrive bit
1017 li r11,T_TRACE ; Set trace interrupt
1018 rlwinm r12,r12,0,16,31 ; Clear top half of SRR1
1019 stw r9,SAVflags(r13) ; Set the flags
1020 stw r11,saveexception(r13) ; Set the exception code
1021 b EXT(EmulExit) ; Exit and do trace interrupt...
1029 mr r20,r1 ; Save the DSISR
1031 lwz r4,SAVflags(r13) ; Pick up the flags
1032 li r11,T_DATA_ACCESS ; Set failing data access code
1033 oris r4,r4,hi16(SAVredrive) ; Set the redrive bit
1034 stw r20,savedsisr(r13) ; Set the DSISR of failed access
1035 stw r21,savedar+4(r13) ; Set the address of the failed access
1036 stw r11,saveexception(r13) ; Set the replacement code
1037 stw r4,SAVflags(r13) ; Set redrive request
1038 b EXT(EmulExit) ; Bail out to handle ISI...
1043 ; Table of functions to load or store floating point registers
1044 ; This table is indexed reg||size||dir. That means that each
1045 ; like load/store pair (e.g., lfd f31/stfd f31) are within the same
1046 ; quadword, which is the current ifetch size. We expect most of the
1047 ; unaligned accesses to be part of copies, therefore, with this
1048 ; organization, we will save the ifetch of the store after the load.
1051 .align 10 ; Make sure we are on a 1k boundary
1052 .globl EXT(aaFPopTable)
1055 lfs f0,emfp0(r31) ; Load single variant
1058 stfs f0,emfp0(r31) ; Store single variant
1061 lfd f0,emfp0(r31) ; Load double variant
1064 stfd f0,emfp0(r31) ; Store double variant
1067 lfs f1,emfp0(r31) ; Load single variant
1070 stfs f1,emfp0(r31) ; Store single variant
1073 lfd f1,emfp0(r31) ; Load double variant
1076 stfd f1,emfp0(r31) ; Store double variant
1079 lfs f2,emfp0(r31) ; Load single variant
1082 stfs f2,emfp0(r31) ; Store single variant
1085 lfd f2,emfp0(r31) ; Load double variant
1088 stfd f2,emfp0(r31) ; Store double variant
1091 lfs f3,emfp0(r31) ; Load single variant
1094 stfs f3,emfp0(r31) ; Store single variant
1097 lfd f3,emfp0(r31) ; Load double variant
1100 stfd f3,emfp0(r31) ; Store double variant
1103 lfs f4,emfp0(r31) ; Load single variant
1106 stfs f4,emfp0(r31) ; Store single variant
1109 lfd f4,emfp0(r31) ; Load double variant
1112 stfd f4,emfp0(r31) ; Store double variant
1115 lfs f5,emfp0(r31) ; Load single variant
1118 stfs f5,emfp0(r31) ; Store single variant
1121 lfd f5,emfp0(r31) ; Load double variant
1124 stfd f5,emfp0(r31) ; Store double variant
1127 lfs f6,emfp0(r31) ; Load single variant
1130 stfs f6,emfp0(r31) ; Store single variant
1133 lfd f6,emfp0(r31) ; Load double variant
1136 stfd f6,emfp0(r31) ; Store double variant
1139 lfs f7,emfp0(r31) ; Load single variant
1142 stfs f7,emfp0(r31) ; Store single variant
1145 lfd f7,emfp0(r31) ; Load double variant
1148 stfd f7,emfp0(r31) ; Store double variant
1151 lfs f8,emfp0(r31) ; Load single variant
1154 stfs f8,emfp0(r31) ; Store single variant
1157 lfd f8,emfp0(r31) ; Load double variant
1160 stfd f8,emfp0(r31) ; Store double variant
1163 lfs f9,emfp0(r31) ; Load single variant
1166 stfs f9,emfp0(r31) ; Store single variant
1169 lfd f9,emfp0(r31) ; Load double variant
1172 stfd f9,emfp0(r31) ; Store double variant
1175 lfs f10,emfp0(r31) ; Load single variant
1178 stfs f10,emfp0(r31) ; Store single variant
1181 lfd f10,emfp0(r31) ; Load double variant
1184 stfd f10,emfp0(r31) ; Store double variant
1187 lfs f11,emfp0(r31) ; Load single variant
1190 stfs f11,emfp0(r31) ; Store single variant
1193 lfd f11,emfp0(r31) ; Load double variant
1196 stfd f11,emfp0(r31) ; Store double variant
1199 lfs f12,emfp0(r31) ; Load single variant
1202 stfs f12,emfp0(r31) ; Store single variant
1205 lfd f12,emfp0(r31) ; Load double variant
1208 stfd f12,emfp0(r31) ; Store double variant
1211 lfs f13,emfp0(r31) ; Load single variant
1214 stfs f13,emfp0(r31) ; Store single variant
1217 lfd f13,emfp0(r31) ; Load double variant
1220 stfd f13,emfp0(r31) ; Store double variant
1223 lfs f14,emfp0(r31) ; Load single variant
1226 stfs f14,emfp0(r31) ; Store single variant
1229 lfd f14,emfp0(r31) ; Load double variant
1232 stfd f14,emfp0(r31) ; Store double variant
1235 lfs f15,emfp0(r31) ; Load single variant
1238 stfs f15,emfp0(r31) ; Store single variant
1241 lfd f15,emfp0(r31) ; Load double variant
1244 stfd f15,emfp0(r31) ; Store double variant
1247 lfs f16,emfp0(r31) ; Load single variant
1250 stfs f16,emfp0(r31) ; Store single variant
1253 lfd f16,emfp0(r31) ; Load double variant
1256 stfd f16,emfp0(r31) ; Store double variant
1259 lfs f17,emfp0(r31) ; Load single variant
1262 stfs f17,emfp0(r31) ; Store single variant
1265 lfd f17,emfp0(r31) ; Load double variant
1268 stfd f17,emfp0(r31) ; Store double variant
1271 lfs f18,emfp0(r31) ; Load single variant
1274 stfs f18,emfp0(r31) ; Store single variant
1277 lfd f18,emfp0(r31) ; Load double variant
1280 stfd f18,emfp0(r31) ; Store double variant
1283 lfs f19,emfp0(r31) ; Load single variant
1286 stfs f19,emfp0(r31) ; Store single variant
1289 lfd f19,emfp0(r31) ; Load double variant
1292 stfd f19,emfp0(r31) ; Store double variant
1295 lfs f20,emfp0(r31) ; Load single variant
1298 stfs f20,emfp0(r31) ; Store single variant
1301 lfd f20,emfp0(r31) ; Load double variant
1304 stfd f20,emfp0(r31) ; Store double variant
1307 lfs f21,emfp0(r31) ; Load single variant
1310 stfs f21,emfp0(r31) ; Store single variant
1313 lfd f21,emfp0(r31) ; Load double variant
1316 stfd f21,emfp0(r31) ; Store double variant
1319 lfs f22,emfp0(r31) ; Load single variant
1322 stfs f22,emfp0(r31) ; Store single variant
1325 lfd f22,emfp0(r31) ; Load double variant
1328 stfd f22,emfp0(r31) ; Store double variant
1331 lfs f23,emfp0(r31) ; Load single variant
1334 stfs f23,emfp0(r31) ; Store single variant
1337 lfd f23,emfp0(r31) ; Load double variant
1340 stfd f23,emfp0(r31) ; Store double variant
1343 lfs f24,emfp0(r31) ; Load single variant
1346 stfs f24,emfp0(r31) ; Store single variant
1349 lfd f24,emfp0(r31) ; Load double variant
1352 stfd f24,emfp0(r31) ; Store double variant
1355 lfs f25,emfp0(r31) ; Load single variant
1358 stfs f25,emfp0(r31) ; Store single variant
1361 lfd f25,emfp0(r31) ; Load double variant
1364 stfd f25,emfp0(r31) ; Store double variant
1367 lfs f26,emfp0(r31) ; Load single variant
1370 stfs f26,emfp0(r31) ; Store single variant
1373 lfd f26,emfp0(r31) ; Load double variant
1376 stfd f26,emfp0(r31) ; Store double variant
1379 lfs f27,emfp0(r31) ; Load single variant
1382 stfs f27,emfp0(r31) ; Store single variant
1385 lfd f27,emfp0(r31) ; Load double variant
1388 stfd f27,emfp0(r31) ; Store double variant
1391 lfs f28,emfp0(r31) ; Load single variant
1394 stfs f28,emfp0(r31) ; Store single variant
1397 lfd f28,emfp0(r31) ; Load double variant
1400 stfd f28,emfp0(r31) ; Store double variant
1403 lfs f29,emfp0(r31) ; Load single variant
1406 stfs f29,emfp0(r31) ; Store single variant
1409 lfd f29,emfp0(r31) ; Load double variant
1412 stfd f29,emfp0(r31) ; Store double variant
1415 lfs f30,emfp0(r31) ; Load single variant
1418 stfs f30,emfp0(r31) ; Store single variant
1421 lfd f30,emfp0(r31) ; Load double variant
1424 stfd f30,emfp0(r31) ; Store double variant
1427 lfs f31,emfp0(r31) ; Load single variant
1430 stfs f31,emfp0(r31) ; Store single variant
1433 lfd f31,emfp0(r31) ; Load double variant
1436 stfd f31,emfp0(r31) ; Store double variant