2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
25 Emulate instructions and traps.
27 Lovingly crafted by Bill Angell using traditional methods and only natural or recycled materials.
28 No animal products are used other than rendered otter bile and deep fried pork lard.
33 #include <ppc/proc_reg.h>
34 #include <ppc/exception.h>
35 #include <ppc/cpu_capabilities.h>
36 #include <mach/machine/vm_param.h>
42 ; General stuff what happens here:
43 ; 1) All general context saved, interrupts off, translation off
44 ; 2) Vector and floating point disabled, but there may be live context.
45 ; This code is responsible for saving and restoring what is used. This
46 ; includes exception states, java mode, etc.
47 ; 3) No attempt is made to resolve page faults. PTE misses are handled
48 ; automatically, but actual faults (ala copyin/copyout) are not. If
49 ; a fault does occur, the exception that caused entry to the emulation
50 ; routine is remapped to either an instruction or data miss (depending
51 ; upon the stage detected) and redrived through the exception handler.
52 ; The only time that an instruction fault can happen is when a different
53 ; processor removes a mapping between our original fault and when we
54 ; fetch the assisted instruction. For an assisted instruction, data
55 ; faults should not occur (except in the MP case). For a purely
56 ; emulated instruction, faults can occur.
66 bf-- pf64Bitb,emn64 ; Skip if not 64-bit
67 b EXT(Emulate64) ; Jump to the 64-bit code...
69 emn64: mfsprg r31,0 ; Get the per_proc
70 lwz r12,savesrr1+4(r13) ; Get the exception info
71 rlwinm. r0,r12,0,SRR1_PRG_ILL_INS_BIT,SRR1_PRG_ILL_INS_BIT ; Emulation candidate?
72 lwz r30,dgFlags(0) ; Get the flags
73 beq+ eExit ; Nope, do not try to emulate...
75 rlwinm. r0,r30,0,enaDiagEMb,enaDiagEMb ; Do we want to try to emulate something?
76 mfsprg r28,2 ; Get the processor features
77 beq+ eExit ; No emulation allowed...
79 rlwinm. r28,r28,0,pfAltivecb,pfAltivecb ; Do we have Altivec on this machine?
80 beq eNoVect ; Nope, no Altivec...
82 dssall ; We need to kill streams because we are going to flip to problem state
85 eNoVect: bl eIFetch ; Get the instruction image
86 bne- eRedriveAsISI ; Go redrive this as an ISI...
88 rlwinm. r0,r10,0,0,5 ; See if we have the "special" op code here
89 rlwinm r20,r10,16,22,31 ; Set rS/rD and rA
90 bne+ eExit ; Not special op, ignore...
92 rlwinm r0,r10,31,22,31 ; Extract the sub op code
94 rlwimi r20,r10,14,15,16 ; Move bits 29 and 30 of instruction to 15 and 16 of DSISR
95 cmplwi r0,790 ; lhbrx?
96 rlwimi r20,r10,8,17,17 ; Move bit 25 to bit 17
97 cror cr1_eq,cr1_eq,cr0_eq ; Remember
98 cmplwi r0,534 ; lwbrx?
99 rlwimi r20,r10,3,18,21 ; Move bit 21-24 to bit 18-21
100 cror cr1_eq,cr1_eq,cr0_eq ; Remember
101 cmplwi r0,918 ; sthbrx?
102 cror cr1_eq,cr1_eq,cr0_eq ; Remember
103 cmplwi r0,662 ; stwbrx?
104 cror cr1_eq,cr1_eq,cr0_eq ; Remember
105 cmplwi r0,1014 ; dcbz?
106 cror cr1_eq,cr1_eq,cr0_eq ; Remember
107 cmplwi r0,533 ; lswx?
108 cror cr1_eq,cr1_eq,cr0_eq ; Remember
109 cmplwi r0,661 ; stswx?
110 cror cr1_eq,cr1_eq,cr0_eq ; Remember
111 bne cr1_eq,eNotIndex ; Go check non-index forms...
113 rlwinm. r21,r10,19,24,28 ; Extract index to rA to build EA
114 rlwinm r22,r10,24,24,28 ; Extract index to rB
115 addi r24,r13,saver0+4 ; Point to the start of registers
116 li r19,0 ; Assume 0 base
117 beq eZeroBase ; Yes...
118 lwzx r19,r24,r21 ; Get the base register value
120 eZeroBase: lwzx r22,r24,r22 ; Get the index value
121 add r22,r22,r19 ; Get DAR
122 b eFinishUp ; Done, go finish up...
124 eNotIndex: cmplwi r0,725 ; stswi?
125 cror cr1_eq,cr1_eq,cr0_eq ; Remember
126 cmplwi r0,597 ; lswi?
127 cror cr1_eq,cr1_eq,cr0_eq ; Remember
128 bne cr1,eExit ; Not one we handle...
130 rlwinm. r21,r10,19,24,28 ; Extract index to rA to build EA
131 addi r24,r13,saver0+4 ; Point to the start of registers
132 li r22,0 ; Assume 0 base
133 beq eFinishUp ; Yes, it is...
134 lwzx r22,r24,r21 ; Get the base register value
136 eFinishUp: stw r20,savedsisr(r13) ; Set the DSISR
137 li r11,T_ALIGNMENT ; Get the exception code
138 stw r22,savedar+4(r13) ; Save the DAR
139 stw r11,saveexception(r13) ; Set the exception code
140 b EXT(AlignAssist) ; Go emulate the handler...
143 eExit: b EXT(EmulExit) ; Just return for now...
147 ; Fetch the failing instruction.
148 ; Image returned in R10 if CR0_EQ is false, otherwise, an ISI should be generated/
149 ; The cr bit kernAccess is set if this was a kernel access.
150 ; R1 has the DSISR if access failed.
155 eIFetch: lwz r23,savesrr1+4(r13) ; Get old MSR
156 mflr r28 ; Save return
158 rlwinm. r22,r23,0,MSR_PR_BIT,MSR_PR_BIT ; Within kernel?
160 mfmsr r30 ; Save the MSR for now
161 lwz r23,savesrr0+4(r13) ; Get instruction address
163 ori r22,r30,lo16(MASK(MSR_DR)|MASK(MSR_RI)) ; Set RI and DR onto access MSR
165 crset cr0_eq ; Set this to see if we failed
166 mtmsr r22 ; Flip DR, RI, and maybe PR on
169 lwz r10,0(r23) ; Fetch the instruction
171 mtmsr r30 ; Trans and RI off
174 mtlr r28 ; Restore the LR
175 blr ; Return with instruction image in R10
183 lwz r6,savesrr1+4(r13) ; Get the srr1 value
184 lwz r4,SAVflags(r13) ; Pick up the flags
185 li r11,T_INSTRUCTION_ACCESS ; Set failing instruction fetch code
186 rlwimi r6,r1,0,0,4 ; Move the DSISR bits to the SRR1
187 oris r4,r4,hi16(SAVredrive) ; Set the redrive bit
188 stw r11,saveexception(r13) ; Set the replacement code
189 stw r4,SAVflags(r13) ; Set redrive request
190 stw r6,savesrr1+4(r13) ; Set the srr1 value
191 b EXT(EmulExit) ; Bail out to handle ISI...
195 ; This code emulates instructions that have failed because of operand
196 ; alignment. We decode the DSISR to figure out what we need to do.
199 ; 0001FC00 - Instruction designation
209 ; 000003E0 - Target/Source register
210 ; 0000001F - Register to update if update form
214 .globl EXT(AlignAssist)
217 bf-- pf64Bitb,aan64 ; Skip if not 64-bit
218 b EXT(AlignAssist64) ; Jump to the 64-bit code...
220 aan64: lwz r20,savedsisr(r13) ; Get the DSISR
221 li r0,0 ; Assume we emulate
222 mfsprg r31,0 ; Get the per_proc
223 mtcrf 0x10,r20 ; Put instruction ID in CR for later
224 lwz r21,spcFlags(r31) ; Grab the special flags
225 stw r0,savemisc3(r13) ; Assume that we emulate ok
226 mtcrf 0x08,r20 ; Put instruction ID in CR for later
227 rlwinm. r0,r21,0,runningVMbit,runningVMbit ; Are we running a VM?
228 mtcrf 0x04,r20 ; Put instruction ID in CR for later
229 lwz r22,savesrr1+4(r13) ; Get the SRR1
230 bne- aaPassAlong ; We are in a VM, no emulation for alignment exceptions...
231 lwz r19,dgFlags(0) ; Get the diagnostics flags
232 crxor iFloat,iOptype1,iOptype2 ; Set this to 0 if both bits are either 0 or 1
233 mr r26,r20 ; Save the DSISR
234 rlwinm. r0,r22,0,MSR_SE_BIT,MSR_SE_BIT ; Were we single stepping?
235 lwz r23,savedar+4(r13) ; Pick up the address that we want to access
236 crnot traceInst,cr0_eq ; Remember if trace is on
238 rlwinm. r0,r19,0,enaNotifyEMb,enaNotifyEMb ; Should we notify that an alignment exception happened?
239 mfmsr r30 ; Save the MSR for now
240 crnot iNotify,cr0_eq ; Remember to tell someone we did this
241 li r29,emfp0 ; Point to work area
242 crxor iFloat,iFloat,iOptype3 ; Set true if we have a floating point instruction
243 dcbz r29,r31 ; Clear and allocate a cache line for us to work in
244 rlwinm r24,r20,3,24,28 ; Get displacement to register to update if update form
245 rlwimi r20,r20,24,28,28 ; Move load/store indication to the bottom of index
246 ori r22,r30,lo16(MASK(MSR_DR)|MASK(MSR_RI)) ; Set RI onto access MSR
247 rlwimi r20,r20,26,27,27 ; Move single/double indication to just above the bottom
248 lis r29,hi16(EXT(aaFPopTable)) ; High part of FP branch table
249 bf- iFloat,aaNotFloat ; This is not a floating point instruction...
250 ori r29,r29,lo16(EXT(aaFPopTable)) ; Low part of FP branch table
252 rlwimi r29,r20,0,22,28 ; Index into table based upon register||iDouble||iStore
253 mtctr r29 ; Get set to call the function
254 bt iStore,aaFPstore ; This is an FP store...
257 ; Here we handle floating point loads
260 aaFPload: crset cr0_eq ; Set this to see if we failed
261 mtmsr r22 ; Flip DR, RI
264 lwz r10,0(r23) ; Get the first word
265 bf- cr0_eq,aaLdNotDbl ; Jump out if we DSIed...
266 bf iDouble,aaLdNotDbl ; this is not a double...
267 lwz r11,4(r23) ; Get the second half
269 aaLdNotDbl: mr r4,r0 ; Save the DAR if we failed the access
271 mtmsr r30 ; Turn off translation again
274 bf- cr0_eq,aaRedriveAsDSI ; Go redrive this as a DSI...
276 stw r10,emfp0(r31) ; Save the first half
277 stw r11,emfp0+4(r31) ; Save the second half, just in case we need it
279 bctrl ; Go set the target FP register
281 b aaComExit ; All done, go exit...
284 ; Here we handle floating point stores
289 aaFPstore: bctrl ; Go save the source FP register
291 lwz r10,emfp0(r31) ; Get first word
292 crandc iDouble,iDouble,iOptype4 ; Change to 4-byte access if stfiwx
293 lwz r11,emfp0+4(r31) ; and the second
294 bf+ iOptype4,aaNotstfiwx ; This is not a stfiwx...
295 mr r10,r11 ; The stfiwx wants to store the second half
298 crset cr0_eq ; Set this to see if we failed
299 mtmsr r22 ; Flip DR, RI
302 stw r10,0(r23) ; Save the first word
303 bf- cr0_eq,aaStNotDbl ; Jump out if we DSIed...
304 bf iDouble,aaStNotDbl ; this is not a double...
305 stw r11,4(r23) ; Save the second half
307 aaStNotDbl: mr r4,r0 ; Save the DAR if we failed the access
311 bf- cr0_eq,aaRedriveAsDSI ; Go redrive this as a DSI...
314 ; Common exit routines
317 aaComExit: lwz r10,savesrr0+4(r13) ; Get the failing instruction address
318 add r24,r24,r13 ; Offset to update register
319 li r11,T_IN_VAIN ; Assume we are all done
320 addi r10,r10,4 ; Step to the next instruction
321 bf iUpdate,aaComExNU ; Skip if not an update form...
322 stw r23,saver0+4(r24) ; Update the target
324 aaComExNU: lwz r9,SAVflags(r13) ; Get the flags
325 stw r10,savesrr0+4(r13) ; Set new PC
326 bt- traceInst,aaComExitrd ; We are tracing, go emulate trace...
327 bf+ iNotify,aaComExGo ; Nothing special here, go...
329 li r11,T_ALIGNMENT ; Set the we just did an alignment exception....
331 aaComExGo: b EXT(EmulExit) ; We are done, no tracing on...
335 ; This is not a floating point operation
337 ; The table of these emulation routines is indexed by taking the low order 4 bits of
338 ; the instruction code in the DSISR and subtracting 7. If this comes up negative,
339 ; the instruction is not to be emulated. Then we add bit 0 of the code * 4. This
340 ; gives us a fairly compact and almost unique index. Both lwm and stmw map to 0 so
341 ; that one needs to be further reduced, and we end up with holes at a few indexes.
347 lis r19,hi16(aaEmTable) ; Point to high part of table address
348 rlwinm r3,r26,24,26,29 ; Isolate last 4 bits of op type * 4
349 rlwimi r19,r26,20,27,27 ; Get bit 0 of instruction code * 4 into bottom of table base
350 addic. r3,r3,-28 ; Subtract 7*4 to adjust index
351 ori r19,r19,lo16(aaEmTable) ; Low part of table address
352 blt- aaPassAlong ; We do not handle any of these (lwarx, stwcx., eciwx, ecowx)...
353 add r19,r19,r3 ; Point to emulation routine
354 rlwinm r18,r26,30,24,28 ; Get the target/source register displacement
356 mtctr r19 ; Set the routine address
358 bctr ; Go emulate the instruction...
361 ; This is the table of non-floating point emulation routines.
362 ; It is indexed by the code immediately above.
367 b aaLmwStmw ; This for lmw/stmw
368 b aaLswx ; This for lwwx
369 b aaLswi ; This for lswi
370 b aaStswx ; This for stswx
371 b aaStswi ; This for stswi
372 b aaLwbrx ; This for lwbrx
373 b aaPassAlong ; This an invalid index (6)
374 b aaStwbrx ; This for stwbrx
375 b aaPassAlong ; This an invalid index (8)
376 b aaLhbrx ; This for lhbrx
377 b aaPassAlong ; This an invalid index (A)
378 b aaSthbrx ; This for sthbrx
379 b aaDcbz ; This for dcbz
380 b aaPassAlong ; This an invalid index (D)
381 b aaPassAlong ; This an invalid index (E)
382 b aaPassAlong ; This an invalid index (F)
386 ; Here we handle the set up for the lmw and stmw. After that, we split off to the
387 ; individual routines.
389 ; Note also that after some set up, all of the string instructions come through here as well.
394 rlwinm r17,r18,31,1,29 ; Convert doublword based index to words
395 li r28,0 ; Set no extra bytes to move (used for string instructions)
396 subfic r17,r17,32*4 ; Calculate the length of the transfer
398 aaLSComm: addi r19,r13,saver0+4 ; Offset to registers in savearea
399 mr r16,r23 ; Make a hunk pointer
401 bt iUpdate,aaStmw ; This is the stmw...
407 aaLmwNxt: cmplwi cr1,r17,8*4 ; Is there enough to move 8?
408 blt- cr1,aaLmwNxtH ; Not enough for a full hunk...
409 subi r17,r17,8*4 ; Back off for another hunk
411 crset cr0_eq ; Set this to see if we failed
412 mtmsr r22 ; Flip DR, RI
415 lwz r2,0(r16) ; Load word 0
416 bf- cr0_eq,aaLmwB1 ; Error, bail...
417 lwz r15,4(r16) ; Load word 1
418 bf- cr0_eq,aaLmwB1 ; Error, bail...
419 lwz r14,8(r16) ; Load word 2
420 bf- cr0_eq,aaLmwB1 ; Error, bail...
421 lwz r5,12(r16) ; Load word 3
422 bf- cr0_eq,aaLmwB1 ; Error, bail...
423 lwz r6,16(r16) ; Load word 4
424 bf- cr0_eq,aaLmwB1 ; Error, bail...
425 lwz r7,20(r16) ; Load word 5
426 bf- cr0_eq,aaLmwB1 ; Error, bail...
427 lwz r8,24(r16) ; Load word 6
428 bf- cr0_eq,aaLmwB1 ; Error, bail...
429 lwz r9,28(r16) ; Load word 7
431 aaLmwB1: mr r4,r0 ; Remember DAR, jus in case we failed the access
432 mtmsr r30 ; Turn off DR, RI
435 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
437 addi r16,r16,8*4 ; Point up to next input aread
439 stwx r2,r19,r18 ; Store register
440 addi r18,r18,8 ; Next register
441 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
442 stwx r15,r19,r18 ; Store register
443 addi r18,r18,8 ; Next register
444 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
445 stwx r14,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 r5,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 r6,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 r7,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 r8,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 r9,r19,r18 ; Store register
461 addi r18,r18,8 ; Next register
462 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
464 b aaLmwNxt ; Do the next hunk...
468 aaLmwNxtH: cmplwi cr1,r17,4*4 ; Do we have 4 left?
469 blt cr1,aaLmwL4 ; Nope...
471 subi r17,r17,4*4 ; Set count properly
473 crset cr0_eq ; Set this to see if we failed
474 mtmsr r22 ; Flip DR, RI, and maybe PR on
477 lwz r2,0(r16) ; Load word 0
478 bf- cr0_eq,aaLmwB2 ; Error, bail...
479 lwz r15,4(r16) ; Load word 1
480 bf- cr0_eq,aaLmwB2 ; Error, bail...
481 lwz r14,8(r16) ; Load word 2
482 bf- cr0_eq,aaLmwB2 ; Error, bail...
483 lwz r5,12(r16) ; Load word 3
485 aaLmwB2: mr r4,r0 ; Remember DAR, jus in case we failed the access
486 mtmsr r30 ; Turn off DR, RI
489 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
491 addi r16,r16,4*4 ; Point up to next input aread
493 stwx r2,r19,r18 ; Store register
494 addi r18,r18,8 ; Next register
495 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
496 stwx r15,r19,r18 ; Store register
497 addi r18,r18,8 ; Next register
498 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
499 stwx r14,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 r5,r19,r18 ; Store register
503 addi r18,r18,8 ; Next register
504 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
506 aaLmwL4: or. r5,r17,r28 ; Do we have anything left?
507 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three full words left?
508 cmplwi cr2,r17,0 ; Do we have no full words left?
509 beq aaComExit ; Nothing left...
511 crset cr0_eq ; Set this to see if we failed
512 mtmsr r22 ; Flip DR, RI, and maybe PR on
515 beq- cr2,aaLmwBy ; No full words, get bytes...
517 lwz r2,0(r16) ; Pick up first word
518 bf- cr0_eq,aaLmwDn ; Read failed, escape...
519 addi r16,r16,4 ; Next input location
520 blt cr1,aaLmwBy ; We only had one, we are done...
522 lwz r15,0(r16) ; Pick up second word
523 bf- cr0_eq,aaLmwDn ; Read failed, escape...
524 addi r16,r16,4 ; Next input location
525 beq cr1,aaLmwBy ; We had two, we are done...
527 lwz r14,0(r16) ; Load word 3
528 addi r16,r16,4 ; Next input location
530 aaLmwBy: cmplwi cr2,r28,0 ; Any trailing bytes to do?
531 li r8,0 ; Clear second trailing byte
532 cmplwi cr1,r28,2 ; Check for 1, 2, or 3
533 li r9,0 ; Clear third trailing byte
534 beq+ cr2,aaLmwDn ; No trailing bytes...
536 lbz r5,0(r16) ; Pick up first trailing byte
537 bf- cr0_eq,aaLmwDn ; Read failed, escape...
538 blt cr1,aaLmwDn ; We only had one, we are done...
540 lbz r8,1(r16) ; Pick up second trailing byte
541 bf- cr0_eq,aaLmwDn ; Read failed, escape...
542 beq cr1,aaLmwDn ; We had two, we are done...
544 lbz r9,2(r16) ; Get last trailing byte
547 aaLmwDn: rlwinm r5,r5,24,0,7 ; Move first byte to top
548 cmplwi cr2,r17,0 ; Any full words to do?
549 mr r4,r0 ; Remember DAR, just in case we failed the access
550 rlwimi r9,r8,8,16,23 ; Move second byte above third byte
551 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three full words left?
552 mr r3,r30 ; Set the normal MSR
553 rlwimi r5,r9,8,8,23 ; Move bytes 1 and 2 after 0
555 mtmsr r30 ; Turn off DR, RI
558 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
560 beq- cr2,aaLmwCb ; No full words, copy bytes...
562 stwx r2,r19,r18 ; Store register
563 addi r18,r18,8 ; Next register
564 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
565 blt cr1,aaLmwCb ; We only had one, we are done...
567 stwx r15,r19,r18 ; Store register
568 addi r18,r18,8 ; Next register
569 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
570 beq cr1,aaLmwCb ; We had two, we are done...
572 stwx r14,r19,r18 ; Store register
573 addi r18,r18,8 ; Next register
574 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
576 aaLmwCb: mr. r28,r28 ; Any trailing bytes to do?
577 beq+ aaComExit ; Nope, leave...
579 stwx r5,r19,r18 ; Store register
581 b aaComExit ; We are done....
584 ; Store multiple word
590 crclr iUpdate ; Make sure we do not think this is an update form
592 aaStmwNxt: cmplwi cr1,r17,8*4 ; Is there enough to move 8?
593 blt- cr1,aaStmwNxtH ; Not enough for a full hunk...
594 subi r17,r17,8*4 ; Back off for another hunk
596 lwzx r2,r19,r18 ; Store register
597 addi r18,r18,8 ; Next register
598 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
599 lwzx r15,r19,r18 ; Store register
600 addi r18,r18,8 ; Next register
601 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
602 lwzx r14,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 r5,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 r6,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 r7,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 r8,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 r9,r19,r18 ; Store register
618 addi r18,r18,8 ; Next register
619 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
621 crset cr0_eq ; Set this to see if we failed
622 mtmsr r22 ; Flip DR, RI, and maybe PR on
625 stw r2,0(r16) ; Store word 0
626 bf- cr0_eq,aaStmwB1 ; Error, bail...
627 stw r15,4(r16) ; Store word 1
628 bf- cr0_eq,aaStmwB1 ; Error, bail...
629 stw r14,8(r16) ; Store word 2
630 bf- cr0_eq,aaStmwB1 ; Error, bail...
631 stw r5,12(r16) ; Store word 3
632 bf- cr0_eq,aaStmwB1 ; Error, bail...
633 stw r6,16(r16) ; Store word 4
634 bf- cr0_eq,aaStmwB1 ; Error, bail...
635 stw r7,20(r16) ; Store word 5
636 bf- cr0_eq,aaStmwB1 ; Error, bail...
637 stw r8,24(r16) ; Store word 6
638 bf- cr0_eq,aaStmwB1 ; Error, bail...
639 stw r9,28(r16) ; Store word 7
641 addi r16,r16,8*4 ; Point up to next output aread
644 aaStmwB1: mr r4,r0 ; Remember DAR, jus in case we failed the access
645 mtmsr r30 ; Normal MSR
648 bt- cr0_eq,aaStmwNxt ; We have more to do and no failed access...
649 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
653 aaStmwNxtH: cmplwi cr1,r17,(4*4) ; Do we have at least 4 left?
654 blt cr1,aaStmwL4 ; Nope...
655 subi r17,r17,4*4 ; Set count properly
657 lwzx r2,r19,r18 ; Store register
658 addi r18,r18,8 ; Next register
659 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
660 lwzx r15,r19,r18 ; Store register
661 addi r18,r18,8 ; Next register
662 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
663 lwzx r14,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 r5,r19,r18 ; Store register
667 addi r18,r18,8 ; Next register
668 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
670 crset cr0_eq ; Set this to see if we failed
671 mtmsr r22 ; Flip DR, RI
674 stw r2,0(r16) ; Store word 0
675 bf- cr0_eq,aaStmwB2 ; Error, bail...
676 stw r15,4(r16) ; Store word 1
677 bf- cr0_eq,aaStmwB2 ; Error, bail...
678 stw r14,8(r16) ; Store word 2
679 bf- cr0_eq,aaStmwB2 ; Error, bail...
680 stw r5,12(r16) ; Store word 3
682 addi r16,r16,4*4 ; Point up to next input aread
684 aaStmwB2: mr r4,r0 ; Remember DAR, jus in case we failed the access
685 mtmsr r30 ; Normal MSR
688 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
690 aaStmwL4: or. r5,r17,r28 ; Do we have anything left to do?
691 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three left?
692 cmplwi cr2,r17,0 ; Do we have no full words left?
693 beq aaComExit ; Nothing left...
695 beq- cr2,aaStmwBy1 ; No full words, check out bytes
697 lwzx r2,r19,r18 ; Store register
698 addi r18,r18,8 ; Next register
699 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
700 blt cr1,aaStmwBy1 ; We only had one, go save it...
702 lwzx r15,r19,r18 ; Store register
703 addi r18,r18,8 ; Next register
704 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
705 beq cr1,aaStmwBy1 ; We had two, go save it...
707 lwzx r14,r19,r18 ; Store register
708 addi r18,r18,8 ; Next register
709 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
711 aaStmwBy1: mr. r28,r28 ; Do we have any trailing bytes?
712 beq+ aaStmwSt ; Nope...
714 lwzx r5,r19,r18 ; Yes, pick up one extra register
716 aaStmwSt: crset cr0_eq ; Set this to see if we failed
717 mtmsr r22 ; Flip DR, RI
720 beq- cr2,aaStmwBy2 ; No words, check trailing bytes...
722 stw r2,0(r16) ; Save first word
723 bf- cr0_eq,aaStmwDn ; Store failed, escape...
724 addi r16,r16,4 ; Bump sink
725 blt cr1,aaStmwBy2 ; We only had one, we are done...
727 stw r15,0(r16) ; Save second word
728 bf- cr0_eq,aaStmwDn ; Store failed, escape...
729 addi r16,r16,4 ; Bump sink
730 beq cr1,aaStmwBy2 ; We had two, we are done...
732 stw r14,0(r16) ; Save third word
733 bf- cr0_eq,aaStmwDn ; Store failed, escape...
734 addi r16,r16,4 ; Bump sink
736 aaStmwBy2: rlwinm r2,r5,8,24,31 ; Get byte 0
737 cmplwi cr2,r28,0 ; Any trailing bytes to do?
738 rlwinm r14,r5,24,24,31 ; Get byte 3
739 li r8,0 ; Clear second trailing byte
740 cmplwi cr1,r28,2 ; Check for 1, 2, or 3
741 li r9,0 ; Clear third trailing byte
742 beq+ cr2,aaStmwDn ; No trailing bytes...
743 rlwinm r15,r5,16,24,31 ; Get byte 1
745 stb r2,0(r16) ; Save first byte
746 bf- cr0_eq,aaStmwDn ; Read failed, escape...
747 blt cr1,aaStmwDn ; We only had one, we are done...
749 stb r15,1(r16) ; Save second byte
750 bf- cr0_eq,aaStmwDn ; Read failed, escape...
751 beq cr1,aaStmwDn ; We had two, we are done...
753 stb r14,2(r16) ; Save third byte
755 aaStmwDn: mr r4,r0 ; Remember DAR, jus in case we failed the access
756 mtmsr r30 ; Normal MSR
759 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
761 b aaComExit ; We are done....
765 ; Load String Indexed
770 aaLswx: lwz r17,savexer+4(r13) ; Pick up the XER
771 crclr iUpdate ; Make sure we think this the load form
772 rlwinm. r25,r17,0,25,31 ; Get the number of bytes to load
773 rlwinm r28,r17,0,30,31 ; Get the number of bytes past an even word
774 beq- aaComExit ; Do nothing if 0 length...
775 xor r17,r25,r28 ; Round down to an even word boundary
776 b aaLSComm ; Join up with common load/store code...
780 ; Load String Immediate
785 aaLswi: mr r9,r23 ; Save the DAR
786 bl eIFetch ; Get the instruction image
787 bne- eRedriveAsISI ; Go redrive this as an ISI...
788 rlwinm r25,r10,21,27,31 ; Get the number of bytes to load
789 crclr iUpdate ; Make sure we think this the load form
790 subi r25,r25,1 ; Back off by 1
791 rlwinm r25,r25,0,27,31 ; Clear back down
792 addi r25,r25,1 ; Add back the 1 to convert 0 to 32
793 rlwinm r28,r25,0,30,31 ; Get the number of bytes past an even word
794 xor r17,r25,r28 ; Round down to an even word boundary
795 mr r23,r9 ; Move back the DAR
796 b aaLSComm ; Join up with common load/store code...
799 ; Store String Indexed
804 aaStswx: lwz r17,savexer+4(r13) ; Pick up the XER
805 crclr iUpdate ; Make sure this is clear in case we have 0 length
806 rlwinm. r25,r17,0,25,31 ; Get the number of bytes to load
807 rlwinm r28,r17,0,30,31 ; Get the number of bytes past an even word
808 beq- aaComExit ; Do nothing if 0 length...
809 xor r17,r25,r28 ; Round down to an even word boundary
810 crset iUpdate ; Make sure we think this the store form
811 b aaLSComm ; Join up with common load/store code...
815 ; Store String Immediate
820 aaStswi: mr r9,r23 ; Save the DAR
821 bl eIFetch ; Get the instruction image
822 bne- eRedriveAsISI ; Go redrive this as an ISI...
823 rlwinm r25,r10,21,27,31 ; Get the number of bytes to load
824 crclr iUpdate ; Make sure we think this the load form
825 subi r25,r25,1 ; Back off by 1
826 rlwinm r25,r25,0,27,31 ; Clear back down
827 addi r25,r25,1 ; Add back the 1 to convert 0 to 32
828 rlwinm r28,r25,21,30,31 ; Get the number of bytes past an even word
829 xor r17,r25,r28 ; Round down to an even word boundary
830 mr r23,r9 ; Move back the DAR
831 b aaLSComm ; Join up with common load/store code...
835 ; Load byte-reversed word
841 add r18,r18,r13 ; Index to source register
843 crset cr0_eq ; Set this to see if we failed
844 mtmsr r22 ; Flip DR, RI, and maybe PR on
847 lwz r11,0(r23) ; Load the word
849 mr r4,r0 ; Save the DAR if we failed the access
850 mtmsr r30 ; Restore normal MSR
853 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
855 rlwinm r10,r11,8,0,31 ; Get byte 0 to 3 and byte 2 to 1
856 rlwimi r10,r11,24,16,23 ; Move byte 1 to byte 2
857 rlwimi r10,r11,24,0,7 ; Move byte 3 to byte 0
859 stw r10,saver0+4(r18) ; Set the register
861 b aaComExit ; All done, go exit...
866 ; Store byte-reversed word
872 add r18,r18,r13 ; Index to source register
873 lwz r11,saver0+4(r18) ; Get the register to store
875 rlwinm r10,r11,8,0,31 ; Get byte 0 to 3 and byte 2 to 1
876 rlwimi r10,r11,24,16,23 ; Move byte 1 to byte 2
877 rlwimi r10,r11,24,0,7 ; Move byte 3 to byte 0
879 crset cr0_eq ; Set this to see if we failed
880 mtmsr r22 ; Flip DR, RI, and maybe PR on
883 stw r10,0(r23) ; Store the reversed halfword
885 mr r4,r0 ; Save the DAR if we failed the access
886 mtmsr r30 ; Restore normal MSR
889 bt+ cr0_eq,aaComExit ; All done, go exit...
890 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
895 ; Load byte-reversed halfword
901 add r18,r18,r13 ; Index to source register
903 crset cr0_eq ; Set this to see if we failed
904 mtmsr r22 ; Flip DR, RI, and maybe PR on
907 lhz r11,0(r23) ; Load the halfword
909 mr r4,r0 ; Save the DAR if we failed the access
910 mtmsr r30 ; Restore normal MSR
913 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
915 rlwinm r10,r11,8,16,23 ; Rotate bottom byte up one and clear everything else
916 rlwimi r10,r11,24,24,31 ; Put old second from bottom into bottom
918 stw r10,saver0+4(r18) ; Set the register
920 b aaComExit ; All done, go exit...
924 ; Store byte-reversed halfword
930 add r18,r18,r13 ; Index to source register
931 lwz r10,saver0+4(r18) ; Get the register to store
932 rlwinm r10,r10,8,0,31 ; Rotate bottom byte up one
933 rlwimi r10,r10,16,24,31 ; Put old second from bottom into bottom
935 crset cr0_eq ; Set this to see if we failed
936 mtmsr r22 ; Flip DR, RI, and maybe PR on
939 sth r10,0(r23) ; Store the reversed halfword
941 mr r4,r0 ; Save the DAR if we failed the access
942 mtmsr r30 ; Restore normal MSR
945 bt+ cr0_eq,aaComExit ; All done, go exit...
946 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
949 ; Data cache block zero
955 lwz r0,savesrr0+4(r13) ; get instruction address
956 li r4,_COMM_PAGE_BASE_ADDRESS
957 rlwinm r23,r23,0,0,26 ; Round EA back to a 32-byte boundary
958 sub r4,r0,r4 ; compute instruction offset from base of commpage
959 cmplwi r4,_COMM_PAGE_AREA_USED ; did fault occur in commpage?
960 bge+ aaDcbz1 ; skip if not in commpage
961 lwz r4,savecr(r13) ; if we take a dcbz in the commpage...
962 rlwinm r4,r4,0,0,27 ; ...clear users cr7 as a flag for commpage code
965 crset cr0_eq ; Set this to see if we failed
966 li r0,0 ; Clear this out
967 mtmsr r22 ; Flip DR, RI, and maybe PR on
970 stw r0,0(r23) ; Clear word
971 bne- aaDcbzXit ; Got DSI, we are stopping...
972 stw r0,4(r23) ; Clear word
973 bne- aaDcbzXit ; Got DSI, we are stopping...
974 stw r0,8(r23) ; Clear word
975 bne- aaDcbzXit ; Got DSI, we are stopping...
976 stw r0,12(r23) ; Clear word
977 bne- aaDcbzXit ; Got DSI, we are stopping...
978 stw r0,16(r23) ; Clear word
979 bne- aaDcbzXit ; Got DSI, we are stopping...
980 stw r0,20(r23) ; Clear word
981 bne- aaDcbzXit ; Got DSI, we are stopping...
982 stw r0,24(r23) ; Clear word
983 bne- aaDcbzXit ; Got DSI, we are stopping...
984 stw r0,28(r23) ; Clear word
986 aaDcbzXit: mr r4,r0 ; Save the DAR if we failed the access
987 mtmsr r30 ; Restore normal MSR
990 crclr iUpdate ; Make sure we do not think this is an update form
992 bt+ cr0_eq,aaComExit ; All done, go exit...
993 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
997 ; Unhandled alignment exception, pass it along
1001 li r0,1 ; Indicate that we failed to emulate
1002 stw r0,savemisc3(r13) ; Assume that we emulate ok
1009 ; We go here to emulate a trace exception after we have handled alignment error
1015 oris r9,r9,hi16(SAVredrive) ; Set the redrive bit
1016 li r11,T_TRACE ; Set trace interrupt
1017 rlwinm r12,r12,0,16,31 ; Clear top half of SRR1
1018 stw r9,SAVflags(r13) ; Set the flags
1019 stw r11,saveexception(r13) ; Set the exception code
1020 b EXT(EmulExit) ; Exit and do trace interrupt...
1028 mr r20,r1 ; Save the DSISR
1030 lwz r4,SAVflags(r13) ; Pick up the flags
1031 li r11,T_DATA_ACCESS ; Set failing data access code
1032 oris r4,r4,hi16(SAVredrive) ; Set the redrive bit
1033 stw r20,savedsisr(r13) ; Set the DSISR of failed access
1034 stw r21,savedar+4(r13) ; Set the address of the failed access
1035 stw r11,saveexception(r13) ; Set the replacement code
1036 stw r4,SAVflags(r13) ; Set redrive request
1037 b EXT(EmulExit) ; Bail out to handle ISI...
1042 ; Table of functions to load or store floating point registers
1043 ; This table is indexed reg||size||dir. That means that each
1044 ; like load/store pair (e.g., lfd f31/stfd f31) are within the same
1045 ; quadword, which is the current ifetch size. We expect most of the
1046 ; unaligned accesses to be part of copies, therefore, with this
1047 ; organization, we will save the ifetch of the store after the load.
1050 .align 10 ; Make sure we are on a 1k boundary
1051 .globl EXT(aaFPopTable)
1054 lfs f0,emfp0(r31) ; Load single variant
1057 stfs f0,emfp0(r31) ; Store single variant
1060 lfd f0,emfp0(r31) ; Load double variant
1063 stfd f0,emfp0(r31) ; Store double variant
1066 lfs f1,emfp0(r31) ; Load single variant
1069 stfs f1,emfp0(r31) ; Store single variant
1072 lfd f1,emfp0(r31) ; Load double variant
1075 stfd f1,emfp0(r31) ; Store double variant
1078 lfs f2,emfp0(r31) ; Load single variant
1081 stfs f2,emfp0(r31) ; Store single variant
1084 lfd f2,emfp0(r31) ; Load double variant
1087 stfd f2,emfp0(r31) ; Store double variant
1090 lfs f3,emfp0(r31) ; Load single variant
1093 stfs f3,emfp0(r31) ; Store single variant
1096 lfd f3,emfp0(r31) ; Load double variant
1099 stfd f3,emfp0(r31) ; Store double variant
1102 lfs f4,emfp0(r31) ; Load single variant
1105 stfs f4,emfp0(r31) ; Store single variant
1108 lfd f4,emfp0(r31) ; Load double variant
1111 stfd f4,emfp0(r31) ; Store double variant
1114 lfs f5,emfp0(r31) ; Load single variant
1117 stfs f5,emfp0(r31) ; Store single variant
1120 lfd f5,emfp0(r31) ; Load double variant
1123 stfd f5,emfp0(r31) ; Store double variant
1126 lfs f6,emfp0(r31) ; Load single variant
1129 stfs f6,emfp0(r31) ; Store single variant
1132 lfd f6,emfp0(r31) ; Load double variant
1135 stfd f6,emfp0(r31) ; Store double variant
1138 lfs f7,emfp0(r31) ; Load single variant
1141 stfs f7,emfp0(r31) ; Store single variant
1144 lfd f7,emfp0(r31) ; Load double variant
1147 stfd f7,emfp0(r31) ; Store double variant
1150 lfs f8,emfp0(r31) ; Load single variant
1153 stfs f8,emfp0(r31) ; Store single variant
1156 lfd f8,emfp0(r31) ; Load double variant
1159 stfd f8,emfp0(r31) ; Store double variant
1162 lfs f9,emfp0(r31) ; Load single variant
1165 stfs f9,emfp0(r31) ; Store single variant
1168 lfd f9,emfp0(r31) ; Load double variant
1171 stfd f9,emfp0(r31) ; Store double variant
1174 lfs f10,emfp0(r31) ; Load single variant
1177 stfs f10,emfp0(r31) ; Store single variant
1180 lfd f10,emfp0(r31) ; Load double variant
1183 stfd f10,emfp0(r31) ; Store double variant
1186 lfs f11,emfp0(r31) ; Load single variant
1189 stfs f11,emfp0(r31) ; Store single variant
1192 lfd f11,emfp0(r31) ; Load double variant
1195 stfd f11,emfp0(r31) ; Store double variant
1198 lfs f12,emfp0(r31) ; Load single variant
1201 stfs f12,emfp0(r31) ; Store single variant
1204 lfd f12,emfp0(r31) ; Load double variant
1207 stfd f12,emfp0(r31) ; Store double variant
1210 lfs f13,emfp0(r31) ; Load single variant
1213 stfs f13,emfp0(r31) ; Store single variant
1216 lfd f13,emfp0(r31) ; Load double variant
1219 stfd f13,emfp0(r31) ; Store double variant
1222 lfs f14,emfp0(r31) ; Load single variant
1225 stfs f14,emfp0(r31) ; Store single variant
1228 lfd f14,emfp0(r31) ; Load double variant
1231 stfd f14,emfp0(r31) ; Store double variant
1234 lfs f15,emfp0(r31) ; Load single variant
1237 stfs f15,emfp0(r31) ; Store single variant
1240 lfd f15,emfp0(r31) ; Load double variant
1243 stfd f15,emfp0(r31) ; Store double variant
1246 lfs f16,emfp0(r31) ; Load single variant
1249 stfs f16,emfp0(r31) ; Store single variant
1252 lfd f16,emfp0(r31) ; Load double variant
1255 stfd f16,emfp0(r31) ; Store double variant
1258 lfs f17,emfp0(r31) ; Load single variant
1261 stfs f17,emfp0(r31) ; Store single variant
1264 lfd f17,emfp0(r31) ; Load double variant
1267 stfd f17,emfp0(r31) ; Store double variant
1270 lfs f18,emfp0(r31) ; Load single variant
1273 stfs f18,emfp0(r31) ; Store single variant
1276 lfd f18,emfp0(r31) ; Load double variant
1279 stfd f18,emfp0(r31) ; Store double variant
1282 lfs f19,emfp0(r31) ; Load single variant
1285 stfs f19,emfp0(r31) ; Store single variant
1288 lfd f19,emfp0(r31) ; Load double variant
1291 stfd f19,emfp0(r31) ; Store double variant
1294 lfs f20,emfp0(r31) ; Load single variant
1297 stfs f20,emfp0(r31) ; Store single variant
1300 lfd f20,emfp0(r31) ; Load double variant
1303 stfd f20,emfp0(r31) ; Store double variant
1306 lfs f21,emfp0(r31) ; Load single variant
1309 stfs f21,emfp0(r31) ; Store single variant
1312 lfd f21,emfp0(r31) ; Load double variant
1315 stfd f21,emfp0(r31) ; Store double variant
1318 lfs f22,emfp0(r31) ; Load single variant
1321 stfs f22,emfp0(r31) ; Store single variant
1324 lfd f22,emfp0(r31) ; Load double variant
1327 stfd f22,emfp0(r31) ; Store double variant
1330 lfs f23,emfp0(r31) ; Load single variant
1333 stfs f23,emfp0(r31) ; Store single variant
1336 lfd f23,emfp0(r31) ; Load double variant
1339 stfd f23,emfp0(r31) ; Store double variant
1342 lfs f24,emfp0(r31) ; Load single variant
1345 stfs f24,emfp0(r31) ; Store single variant
1348 lfd f24,emfp0(r31) ; Load double variant
1351 stfd f24,emfp0(r31) ; Store double variant
1354 lfs f25,emfp0(r31) ; Load single variant
1357 stfs f25,emfp0(r31) ; Store single variant
1360 lfd f25,emfp0(r31) ; Load double variant
1363 stfd f25,emfp0(r31) ; Store double variant
1366 lfs f26,emfp0(r31) ; Load single variant
1369 stfs f26,emfp0(r31) ; Store single variant
1372 lfd f26,emfp0(r31) ; Load double variant
1375 stfd f26,emfp0(r31) ; Store double variant
1378 lfs f27,emfp0(r31) ; Load single variant
1381 stfs f27,emfp0(r31) ; Store single variant
1384 lfd f27,emfp0(r31) ; Load double variant
1387 stfd f27,emfp0(r31) ; Store double variant
1390 lfs f28,emfp0(r31) ; Load single variant
1393 stfs f28,emfp0(r31) ; Store single variant
1396 lfd f28,emfp0(r31) ; Load double variant
1399 stfd f28,emfp0(r31) ; Store double variant
1402 lfs f29,emfp0(r31) ; Load single variant
1405 stfs f29,emfp0(r31) ; Store single variant
1408 lfd f29,emfp0(r31) ; Load double variant
1411 stfd f29,emfp0(r31) ; Store double variant
1414 lfs f30,emfp0(r31) ; Load single variant
1417 stfs f30,emfp0(r31) ; Store single variant
1420 lfd f30,emfp0(r31) ; Load double variant
1423 stfd f30,emfp0(r31) ; Store double variant
1426 lfs f31,emfp0(r31) ; Load single variant
1429 stfs f31,emfp0(r31) ; Store single variant
1432 lfd f31,emfp0(r31) ; Load double variant
1435 stfd f31,emfp0(r31) ; Store double variant