2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
28 Emulate instructions and traps.
30 Lovingly crafted by Bill Angell using traditional methods and only natural or recycled materials.
31 No animal products are used other than rendered otter bile and deep fried pork lard.
37 #include <ppc/proc_reg.h>
38 #include <ppc/exception.h>
39 #include <mach/machine/vm_param.h>
46 ; General stuff what happens here:
47 ; 1) All general context saved, interrupts off, translation off
48 ; 2) Vector and floating point disabled, but there may be live context.
49 ; This code is responsible for saving and restoring what is used. This
50 ; includes exception states, java mode, etc.
51 ; 3) No attempt is made to resolve page faults. PTE misses are handled
52 ; automatically, but actual faults (ala copyin/copyout) are not. If
53 ; a fault does occur, the exception that caused entry to the emulation
54 ; routine is remapped to either an instruction or data miss (depending
55 ; upon the stage detected) and redrived through the exception handler.
56 ; The only time that an instruction fault can happen is when a different
57 ; processor removes a mapping between our original fault and when we
58 ; fetch the assisted instruction. For an assisted instruction, data
59 ; faults should not occur (except in the MP case). For a purely
60 ; emulated instruction, faults can occur.
71 mfsprg r31,0 ; Get the per_proc
72 lis r30,hi16(EXT(dgWork)) ; Get the high half of diagnostic work area
73 lwz r12,savesrr1(r13) ; Get the exception info
74 ori r30,r30,lo16(EXT(dgWork)) ; And the low half
75 rlwinm. r0,r12,0,SRR1_PRG_ILL_INS_BIT,SRR1_PRG_ILL_INS_BIT ; Emulation candidate?
76 lwz r30,dgFlags(r30) ; Get the flags
77 beq+ eExit ; Nope, do not try to emulate...
79 rlwinm. r0,r30,0,enaDiagEMb,enaDiagEMb ; Do we want to try to emulate something?
80 mfsprg r28,2 ; Get the processor features
81 beq+ eExit ; No emulation allowed...
83 rlwinm. r28,r28,0,pfAltivecb,pfAltivecb ; Do we have Altivec on this machine?
84 beq eNoVect ; Nope, no Altivec...
86 dssall ; We need to kill streams because we are going to flip to problem state
89 eNoVect: bl eIFetch ; Get the instruction image
90 bne- eRedriveAsISI ; Go redrive this as an ISI...
92 rlwinm. r0,r10,0,0,5 ; See if we have the "special" op code here
93 rlwinm r20,r10,16,22,31 ; Set rS/rD and rA
94 bne+ eExit ; Not special op, ignore...
96 rlwinm r0,r10,31,22,31 ; Extract the sub op code
98 rlwimi r20,r10,14,15,16 ; Move bits 29 and 30 of instruction to 15 and 16 of DSISR
99 cmplwi r0,790 ; lhbrx?
100 rlwimi r20,r10,8,17,17 ; Move bit 25 to bit 17
101 cror cr1_eq,cr1_eq,cr0_eq ; Remember
102 cmplwi r0,534 ; lwbrx?
103 rlwimi r20,r10,3,18,21 ; Move bit 21-24 to bit 18-21
104 cror cr1_eq,cr1_eq,cr0_eq ; Remember
105 cmplwi r0,918 ; sthbrx?
106 cror cr1_eq,cr1_eq,cr0_eq ; Remember
107 cmplwi r0,662 ; stwbrx?
108 cror cr1_eq,cr1_eq,cr0_eq ; Remember
109 cmplwi r0,1014 ; dcbz?
110 cror cr1_eq,cr1_eq,cr0_eq ; Remember
111 cmplwi r0,533 ; lswx?
112 cror cr1_eq,cr1_eq,cr0_eq ; Remember
113 cmplwi r0,661 ; stswx?
114 cror cr1_eq,cr1_eq,cr0_eq ; Remember
115 bne cr1_eq,eNotIndex ; Go check non-index forms...
117 rlwinm. r21,r10,18,25,29 ; Extract index to rA to build EA
118 rlwinm r22,r10,23,25,29 ; Extract index to rB
119 addi r24,r13,saver0 ; Point to the start of registers
120 li r19,0 ; Assume 0 base
121 beq eZeroBase ; Yes...
122 lwzx r19,r24,r21 ; Get the base register value
124 eZeroBase: lwzx r22,r24,r22 ; Get the index value
125 add r22,r22,r19 ; Get DAR
126 b eFinishUp ; Done, go finish up...
128 eNotIndex: cmplwi r0,725 ; stswi?
129 cror cr1_eq,cr1_eq,cr0_eq ; Remember
130 cmplwi r0,597 ; lswi?
131 cror cr1_eq,cr1_eq,cr0_eq ; Remember
132 bne cr1,eExit ; Not one we handle...
134 rlwinm. r21,r10,18,25,29 ; Extract index to rA to build EA
135 addi r24,r13,saver0 ; Point to the start of registers
136 li r22,0 ; Assume 0 base
137 beq eFinishUp ; Yes, it is...
138 lwzx r22,r24,r21 ; Get the base register value
140 eFinishUp: stw r20,savedsisr(r13) ; Set the DSISR
141 li r11,T_ALIGNMENT ; Get the exception code
142 stw r22,savedar(r13) ; Save the DAR
143 stw r11,saveexception(r13) ; Set the exception code
144 b EXT(AlignAssist) ; Go emulate the handler...
147 eExit: b EXT(EmulExit) ; Just return for now...
151 ; Fetch the failing instruction.
152 ; Image returned in R10 if CR0_EQ is false, otherwise, an ISI should be generated/
153 ; The cr bit kernAccess is set if this was a kernel access.
154 ; R1 has the DSISR if access failed.
159 eIFetch: lwz r23,savesrr1(r13) ; Get old MSR
160 mflr r28 ; Save return
162 rlwinm. r22,r23,0,MSR_PR_BIT,MSR_PR_BIT ; Within kernel?
164 mfmsr r30 ; Save the MSR for now
165 lwz r23,savesrr0(r13) ; Get instruction address
166 crmove kernAccess,cr0_eq ; Remember if fault was in kernel
167 li r25,4 ; Set access length
168 or r22,r22,r30 ; Add PR to access MSR
170 bfl+ kernAccess,aaSetSegs ; Go set SRs if we are in user and need to
172 ori r22,r22,lo16(MASK(MSR_DR)|MASK(MSR_RI)) ; Set RI onto access MSR
174 crset cr0_eq ; Set this to see if we failed
175 mtmsr r22 ; Flip DR, RI, and maybe PR on
178 lwz r10,0(r23) ; Fetch the instruction
180 crmove 28,cr0_eq ; Remember if we failed
181 li r0,loadMSR ; Set the magic "get back to supervisor" SC
182 mr r3,r30 ; Get MSR to load
183 sc ; Get back to supervisor state
185 bfl+ kernAccess,aaUnSetSegs ; Go set SRs if we are in user and need to
187 mtlr r28 ; Restore the LR
188 crmove cr0_eq,28 ; Set CR0_EQ if the fetch succeeded
189 blr ; Return with instruction image in R10
197 lwz r6,savesrr1(r13) ; Get the srr1 value
198 lwz r4,SAVflags(r13) ; Pick up the flags
199 li r11,T_INSTRUCTION_ACCESS ; Set failing instruction fetch code
200 rlwimi r6,r1,0,0,4 ; Move the DSISR bits to the SRR1
201 oris r4,r4,hi16(SAVredrive) ; Set the redrive bit
202 stw r11,saveexception(r13) ; Set the replacement code
203 stw r4,SAVflags(r13) ; Set redrive request
204 stw r6,savesrr1(r13) ; Set the srr1 value
205 b EXT(EmulExit) ; Bail out to handle ISI...
209 ; This code emulates instructions that have failed because of operand
210 ; alignment. We decode the DSISR to figure out what we need to do.
213 ; 0001FC00 - Instruction designation
223 ; 000003E0 - Target/Source register
224 ; 0000001F - Register to update if update form
228 .globl EXT(AlignAssist)
233 b EXT(EmulExit) ; Just return for now...
237 mfsprg r31,0 ; Get the per_proc
238 lwz r20,savedsisr(r13) ; Get the DSISR
239 lwz r21,spcFlags(r31) ; Grab the special flags
240 mtcrf 0x1C,r20 ; Put instruction ID in CR for later
241 rlwinm. r0,r21,0,runningVMbit,runningVMbit ; Are we running a VM?
242 lwz r22,savesrr1(r13) ; Get the SRR1
243 bne- aaPassAlong ; We are in a VM, no emulation for alignment exceptions...
244 rlwinm. r0,r21,0,trapUnalignbit,trapUnalignbit ; Should we trap alignment exceptions?
245 crxor iFloat,iOptype1,iOptype2 ; Set this to 0 if both bits are either 0 or 1
246 mr r26,r20 ; Save the DSISR
247 bne- aaPassAlong ; No alignment exceptions allowed...
248 rlwinm. r0,r22,0,MSR_SE_BIT,MSR_SE_BIT ; Were we single stepping?
249 lwz r23,savedar(r13) ; Pick up the address that we want to access
250 crnot traceInst,cr0_eq ; Remember if trace is on
251 rlwinm. r0,r21,0,notifyUnalignbit,notifyUnalignbit ; Should we notify that an alignment exception happened?
252 mfsprg r28,2 ; Get the processor features
253 crnot iNotify,cr0_eq ; Remember to tell someone we did this
254 rlwinm. r22,r22,0,MSR_PR_BIT,MSR_PR_BIT ; Did we take the exception in the kernel and isolate PR?
255 mfmsr r30 ; Save the MSR for now
256 li r29,emfp0 ; Point to work area
257 crxor iFloat,iFloat,iOptype3 ; Set true if we have a floating point instruction
258 or r22,r22,r30 ; Add PR to access MSR
259 dcbz r29,r31 ; Clear and allocate a cache line for us to work in
260 rlwinm r24,r20,2,25,29 ; Get displacement to register to update if update form
261 rlwimi r20,r20,24,28,28 ; Move load/store indication to the bottom of index
262 ori r22,r22,lo16(MASK(MSR_DR)|MASK(MSR_RI)) ; Set RI onto access MSR
263 crmove kernAccess,cr0_eq ; Remember if fault was in kernel
264 rlwinm. r28,r28,0,pfAltivecb,pfAltivecb ; Do we have Altivec on this machine?
265 rlwimi r20,r20,26,27,27 ; Move single/double indication to just above the bottom
266 beq aaNoVect ; Nope, no Altivec...
268 dssall ; We need to kill streams because we are going to flip to problem state
271 aaNoVect: lis r29,hi16(aaFPopTable) ; High part of FP branch table
272 bf- iFloat,aaNotFloat ; This is not a floating point instruction...
273 li r25,8 ; Assume 8-byte access for now
274 ori r29,r29,lo16(aaFPopTable) ; Low part of FP branch table
275 bt iDouble,aaFPis8 ; So far, we think we are a double...
276 li r25,4 ; Set word access
278 aaFPis8: rlwimi r29,r20,0,22,28 ; Index into table based upon register||iDouble||iStore
279 ori r0,r30,lo16(MASK(MSR_FP)) ; Turn on floating point
280 mtctr r29 ; Get set to call the function
281 bt iStore,aaFPstore ; This is an FP store...
284 ; Here we handle floating point loads
287 aaFPload: bfl+ kernAccess,aaSetSegs ; Go set SRs if we are in user and need to
289 crset cr0_eq ; Set this to see if we failed
290 ori r3,r30,lo16(MASK(MSR_FP)) ; We will need FP on in a bit, so turn on when we ditch problem state
291 mtmsr r22 ; Flip DR, RI, and maybe PR on
294 lwz r10,0(r23) ; Get the first word
295 bf- cr0_eq,aaLdNotDbl ; Jump out if we DSIed...
296 bf iDouble,aaLdNotDbl ; this is not a double...
297 lwz r11,4(r23) ; Get the second half
299 aaLdNotDbl: mr r4,r0 ; Save the DAR if we failed the access
300 li r0,loadMSR ; Set the magic "get back to supervisor" SC
301 sc ; Get back to supervisor state and turn on FP
303 bf- cr0_eq,aaRedriveAsDSI ; Go redrive this as a DSI...
305 stw r10,emfp0(r31) ; Save the first half
306 stw r11,emfp0+4(r31) ; Save the second half, just in case we need it
308 bctrl ; Go set the target FP register
310 b aaComExit ; All done, go exit...
313 ; Here we handle floating point stores
318 aaFPstore: mtmsr r0 ; We need floating point on for the first phase
321 bctrl ; Go save the source FP register
323 lwz r10,emfp0(r31) ; Get first word
324 crandc iDouble,iDouble,iOptype4 ; Change to 4-byte access if stfiwx
325 lwz r11,emfp0+4(r31) ; and the second
326 bf+ iOptype4,aaNotstfiwx ; This is not a stfiwx...
327 li r25,4 ; Set this is a word
328 mr r10,r11 ; The stfiwx wants to store the second half
331 bfl+ kernAccess,aaSetSegs ; Go set SRs if we are in user and need to
333 crset cr0_eq ; Set this to see if we failed
334 mr r3,r30 ; Set the normal MSR
335 mtmsr r22 ; Flip DR, RI, and maybe PR on
338 stw r10,0(r23) ; Save the first word
339 bf- cr0_eq,aaStNotDbl ; Jump out if we DSIed...
340 bf iDouble,aaStNotDbl ; this is not a double...
341 stw r11,4(r23) ; Save the second half
343 aaStNotDbl: mr r4,r0 ; Save the DAR if we failed the access
344 li r0,loadMSR ; Set the magic "get back to supervisor" SC
345 sc ; Get back to supervisor state
348 bf- cr0_eq,aaRedriveAsDSI ; Go redrive this as a DSI...
353 ; Common exit routines
356 aaComExit: lwz r10,savesrr0(r13) ; Get the failing instruction address
357 add r24,r24,r13 ; Offset to update register
358 li r11,T_IN_VAIN ; Assume we are all done
359 addi r10,r10,4 ; Step to the next instruction
360 bf iUpdate,aaComExNU ; Skip if not an update form...
361 stw r23,saver0(r24) ; Update the target
363 aaComExNU: lwz r9,SAVflags(r13) ; Get the flags
364 stw r10,savesrr0(r13) ; Set new PC
365 bt- traceInst,aaComExitrd ; We are tracing, go emulate trace...
366 bf+ iNotify,aaComExGo ; Nothing special here, go...
368 bfl+ kernAccess,aaUnSetSegs ; Go set SRs if we are in user and need to
370 li r11,T_ALIGNMENT ; Set the we just did an alignment exception....
372 aaComExGo: b EXT(EmulExit) ; We are done, no tracing on...
376 ; This is not a floating point operation
378 ; The emulation routines for these are positioned every 64 bytes (16 instructions)
379 ; in a 1024-byte aligned table. It is indexed by taking the low order 4 bits of
380 ; the instruction code in the DSISR and subtracting 7. If this comes up negative,
381 ; the instruction is not to be emulated. Then we add bit 0 of the code * 4. This
382 ; gives us a fairly compact and almost unique index. Both lwm and stmw map to 0 so
383 ; that one needs to be further reduced, and we end up with holes at index 6, 8, and 10.
385 ; If the emulation routine takes more than 16 instructions, it must branch elsewhere
392 lis r19,hi16(aaEmTable) ; Point to high part of table address
393 rlwinm r3,r26,24,26,29 ; Isolate last 4 bits of op type * 4
394 rlwimi r19,r26,20,27,27 ; Get bit 0 of instruction code * 4 into bottom of table base
395 addic. r3,r3,-28 ; Subtract 7*4 to adjust index
396 ori r19,r19,lo16(aaEmTable) ; Low part of table address
397 blt- aaPassAlong ; We do not handle any of these (lwarx, stwcx., eciwx, ecowx)...
398 add r19,r19,r3 ; Point to emulation routine
399 rlwinm r18,r26,29,25,29 ; Get the target/source register displacement
401 mtctr r19 ; Set the routine address
403 bctr ; Go emulate the instruction...
406 ; This is the table of non-floating point emulation routines.
407 ; It is indexed by low 4 bits of DSISR op type - 7 + bit 0 of
414 b aaLmwStmw ; This for lmw/stmw
415 b aaLswx ; This for lwwx
416 b aaLswi ; This for lswi
417 b aaStswx ; This for stswx
418 b aaStswi ; This for stswi
419 b aaLwbrx ; This for lwbrx
420 b aaPassAlong ; This an invalid index (6)
421 b aaStwbrx ; This for stwbrx
422 b aaPassAlong ; This an invalid index (8)
423 b aaLhbrx ; This for lhbrx
424 b aaPassAlong ; This an invalid index (A)
425 b aaSthbrx ; This for sthbrx
426 b aaDcbz ; This for dcbz
427 b aaPassAlong ; This an invalid index (D)
428 b aaPassAlong ; This an invalid index (E)
429 b aaPassAlong ; This an invalid index (F)
433 ; Here we handle the set up for the lmw and stmw. After that, we split off to the
434 ; individual routines.
436 ; Note also that after some set up, all of the string instructions come through here as well.
441 subfic r25,r18,32*4 ; Calculate the length of the transfer
442 li r28,0 ; Set no extra bytes to move (used for string instructions)
443 mr r17,r25 ; Save the word transfer length here
445 aaLSComm: addi r19,r13,saver0 ; Offset to registers in savearea
446 mr r16,r23 ; Make a hunk pointer
448 bfl+ kernAccess,aaSetSegs ; Go set SRs if we are in user and need to
450 bt iUpdate,aaStmw ; This is the stmw...
456 aaLmwNxt: cmplwi cr1,r17,8*4 ; Is there enough to move 8?
457 blt- cr1,aaLmwNxtH ; Not enough for a full hunk...
458 subi r17,r17,8*4 ; Back off for another hunk
460 crset cr0_eq ; Set this to see if we failed
461 mtmsr r22 ; Flip DR, RI, and maybe PR on
464 lwz r2,0(r16) ; Load word 0
465 bf- cr0_eq,aaLmwB1 ; Error, bail...
466 lwz r15,4(r16) ; Load word 1
467 bf- cr0_eq,aaLmwB1 ; Error, bail...
468 lwz r14,8(r16) ; Load word 2
469 bf- cr0_eq,aaLmwB1 ; Error, bail...
470 lwz r5,12(r16) ; Load word 3
471 bf- cr0_eq,aaLmwB1 ; Error, bail...
472 lwz r6,16(r16) ; Load word 4
473 bf- cr0_eq,aaLmwB1 ; Error, bail...
474 lwz r7,20(r16) ; Load word 5
475 bf- cr0_eq,aaLmwB1 ; Error, bail...
476 lwz r8,24(r16) ; Load word 6
477 bf- cr0_eq,aaLmwB1 ; Error, bail...
478 lwz r9,28(r16) ; Load word 7
480 aaLmwB1: mr r4,r0 ; Remember DAR, jus in case we failed the access
481 mr r3,r30 ; Set the normal MSR
482 li r0,loadMSR ; Set the magic "get back to supervisor" SC
483 sc ; Get back to supervisor state
485 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
487 addi r16,r16,8*4 ; Point up to next input aread
489 stwx r2,r19,r18 ; Store register
490 addi r18,r18,4 ; Next register
491 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
492 stwx r15,r19,r18 ; Store register
493 addi r18,r18,4 ; Next register
494 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
495 stwx r14,r19,r18 ; Store register
496 addi r18,r18,4 ; Next register
497 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
498 stwx r5,r19,r18 ; Store register
499 addi r18,r18,4 ; Next register
500 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
501 stwx r6,r19,r18 ; Store register
502 addi r18,r18,4 ; Next register
503 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
504 stwx r7,r19,r18 ; Store register
505 addi r18,r18,4 ; Next register
506 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
507 stwx r8,r19,r18 ; Store register
508 addi r18,r18,4 ; Next register
509 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
510 stwx r9,r19,r18 ; Store register
511 addi r18,r18,4 ; Next register
512 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
514 b aaLmwNxt ; Do the next hunk...
518 aaLmwNxtH: cmplwi cr1,r17,4*4 ; Do we have 4 left?
519 blt cr1,aaLmwL4 ; Nope...
521 subi r17,r17,4*4 ; Set count properly
523 crset cr0_eq ; Set this to see if we failed
524 mtmsr r22 ; Flip DR, RI, and maybe PR on
527 lwz r2,0(r16) ; Load word 0
528 bf- cr0_eq,aaLmwB2 ; Error, bail...
529 lwz r15,4(r16) ; Load word 1
530 bf- cr0_eq,aaLmwB2 ; Error, bail...
531 lwz r14,8(r16) ; Load word 2
532 bf- cr0_eq,aaLmwB2 ; Error, bail...
533 lwz r5,12(r16) ; Load word 3
535 aaLmwB2: mr r4,r0 ; Remember DAR, jus in case we failed the access
536 mr r3,r30 ; Set the normal MSR
537 li r0,loadMSR ; Set the magic "get back to supervisor" SC
538 sc ; Get back to supervisor state
540 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
542 addi r16,r16,4*4 ; Point up to next input aread
544 stwx r2,r19,r18 ; Store register
545 addi r18,r18,4 ; Next register
546 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
547 stwx r15,r19,r18 ; Store register
548 addi r18,r18,4 ; Next register
549 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
550 stwx r14,r19,r18 ; Store register
551 addi r18,r18,4 ; Next register
552 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
553 stwx r5,r19,r18 ; Store register
554 addi r18,r18,4 ; Next register
555 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
557 aaLmwL4: or. r5,r17,r28 ; Do we have anything left?
558 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three full words left?
559 cmplwi cr2,r17,0 ; Do we have no full words left?
560 beq aaComExit ; Nothing left...
562 crset cr0_eq ; Set this to see if we failed
563 mtmsr r22 ; Flip DR, RI, and maybe PR on
566 beq- cr2,aaLmwBy ; No full words, get bytes...
568 lwz r2,0(r16) ; Pick up first word
569 bf- cr0_eq,aaLmwDn ; Read failed, escape...
570 addi r16,r16,4 ; Next input location
571 blt cr1,aaLmwBy ; We only had one, we are done...
573 lwz r15,0(r16) ; Pick up second word
574 bf- cr0_eq,aaLmwDn ; Read failed, escape...
575 addi r16,r16,4 ; Next input location
576 beq cr1,aaLmwBy ; We had two, we are done...
578 lwz r14,0(r16) ; Load word 3
579 addi r16,r16,4 ; Next input location
581 aaLmwBy: cmplwi cr2,r28,0 ; Any trailing bytes to do?
582 li r8,0 ; Clear second trailing byte
583 cmplwi cr1,r28,2 ; Check for 1, 2, or 3
584 li r9,0 ; Clear third trailing byte
585 beq+ cr2,aaLmwDn ; No trailing bytes...
587 lbz r5,0(r16) ; Pick up first trailing byte
588 bf- cr0_eq,aaLmwDn ; Read failed, escape...
589 blt cr1,aaLmwDn ; We only had one, we are done...
591 lbz r8,1(r16) ; Pick up second trailing byte
592 bf- cr0_eq,aaLmwDn ; Read failed, escape...
593 beq cr1,aaLmwDn ; We had two, we are done...
595 lbz r9,2(r16) ; Get last trailing byte
598 aaLmwDn: rlwinm r5,r5,24,0,7 ; Move first byte to top
599 cmplwi cr2,r17,0 ; Any full words to do?
600 mr r4,r0 ; Remember DAR, just in case we failed the access
601 rlwimi r9,r8,8,16,23 ; Move second byte above third byte
602 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three full words left?
603 mr r3,r30 ; Set the normal MSR
604 rlwimi r5,r9,8,8,23 ; Move bytes 1 and 2 after 0
605 li r0,loadMSR ; Set the magic "get back to supervisor" SC
606 sc ; Get back to supervisor state
608 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
610 beq- cr2,aaLmwCb ; No full words, copy bytes...
612 stwx r2,r19,r18 ; Store register
613 addi r18,r18,4 ; Next register
614 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
615 blt cr1,aaLmwCb ; We only had one, we are done...
617 stwx r15,r19,r18 ; Store register
618 addi r18,r18,4 ; Next register
619 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
620 beq cr1,aaLmwCb ; We had two, we are done...
622 stwx r14,r19,r18 ; Store register
623 addi r18,r18,4 ; Next register
624 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
626 aaLmwCb: mr. r28,r28 ; Any trailing bytes to do?
627 beq+ aaComExit ; Nope, leave...
629 stwx r5,r19,r18 ; Store register
631 b aaComExit ; We are done....
634 ; Store multiple word
640 crclr iUpdate ; Make sure we do not think this is an update form
642 aaStmwNxt: cmplwi cr1,r17,8*4 ; Is there enough to move 8?
643 blt- cr1,aaStmwNxtH ; Not enough for a full hunk...
644 subi r17,r17,8*4 ; Back off for another hunk
646 lwzx r2,r19,r18 ; Store register
647 addi r18,r18,4 ; Next register
648 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
649 lwzx r15,r19,r18 ; Store register
650 addi r18,r18,4 ; Next register
651 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
652 lwzx r14,r19,r18 ; Store register
653 addi r18,r18,4 ; Next register
654 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
655 lwzx r5,r19,r18 ; Store register
656 addi r18,r18,4 ; Next register
657 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
658 lwzx r6,r19,r18 ; Store register
659 addi r18,r18,4 ; Next register
660 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
661 lwzx r7,r19,r18 ; Store register
662 addi r18,r18,4 ; Next register
663 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
664 lwzx r8,r19,r18 ; Store register
665 addi r18,r18,4 ; Next register
666 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
667 lwzx r9,r19,r18 ; Store register
668 addi r18,r18,4 ; Next register
669 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
671 crset cr0_eq ; Set this to see if we failed
672 mtmsr r22 ; Flip DR, RI, and maybe PR on
675 stw r2,0(r16) ; Store word 0
676 bf- cr0_eq,aaStmwB1 ; Error, bail...
677 stw r15,4(r16) ; Store word 1
678 bf- cr0_eq,aaStmwB1 ; Error, bail...
679 stw r14,8(r16) ; Store word 2
680 bf- cr0_eq,aaStmwB1 ; Error, bail...
681 stw r5,12(r16) ; Store word 3
682 bf- cr0_eq,aaStmwB1 ; Error, bail...
683 stw r6,16(r16) ; Store word 4
684 bf- cr0_eq,aaStmwB1 ; Error, bail...
685 stw r7,20(r16) ; Store word 5
686 bf- cr0_eq,aaStmwB1 ; Error, bail...
687 stw r8,24(r16) ; Store word 6
688 bf- cr0_eq,aaStmwB1 ; Error, bail...
689 stw r9,28(r16) ; Store word 7
691 addi r16,r16,8*4 ; Point up to next output aread
694 aaStmwB1: mr r4,r0 ; Remember DAR, jus in case we failed the access
695 mr r3,r30 ; Set the normal MSR
696 li r0,loadMSR ; Set the magic "get back to supervisor" SC
697 sc ; Get back to supervisor state
699 bt- cr0_eq,aaStmwNxt ; We have more to do and no failed access...
700 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
704 aaStmwNxtH: cmplwi cr1,r17,(4*4) ; Do we have at least 4 left?
705 blt cr1,aaStmwL4 ; Nope...
706 subi r17,r17,4*4 ; Set count properly
708 lwzx r2,r19,r18 ; Store register
709 addi r18,r18,4 ; Next register
710 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
711 lwzx r15,r19,r18 ; Store register
712 addi r18,r18,4 ; Next register
713 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
714 lwzx r14,r19,r18 ; Store register
715 addi r18,r18,4 ; Next register
716 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
717 lwzx r5,r19,r18 ; Store register
718 addi r18,r18,4 ; Next register
719 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
721 crset cr0_eq ; Set this to see if we failed
722 mtmsr r22 ; Flip DR, RI, and maybe PR on
725 stw r2,0(r16) ; Store word 0
726 bf- cr0_eq,aaStmwB2 ; Error, bail...
727 stw r15,4(r16) ; Store word 1
728 bf- cr0_eq,aaStmwB2 ; Error, bail...
729 stw r14,8(r16) ; Store word 2
730 bf- cr0_eq,aaStmwB2 ; Error, bail...
731 stw r5,12(r16) ; Store word 3
733 addi r16,r16,4*4 ; Point up to next input aread
735 aaStmwB2: mr r4,r0 ; Remember DAR, jus in case we failed the access
736 mr r3,r30 ; Set the normal MSR
737 li r0,loadMSR ; Set the magic "get back to supervisor" SC
738 sc ; Get back to supervisor state
740 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
742 aaStmwL4: or. r5,r17,r28 ; Do we have anything left to do?
743 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three left?
744 cmplwi cr2,r17,0 ; Do we have no full words left?
745 beq aaComExit ; Nothing left...
747 beq- cr2,aaStmwBy1 ; No full words, check out bytes
749 lwzx r2,r19,r18 ; Store register
750 addi r18,r18,4 ; Next register
751 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
752 blt cr1,aaStmwBy1 ; We only had one, go save it...
754 lwzx r15,r19,r18 ; Store register
755 addi r18,r18,4 ; Next register
756 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
757 beq cr1,aaStmwBy1 ; We had two, go save it...
759 lwzx r14,r19,r18 ; Store register
760 addi r18,r18,4 ; Next register
761 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
763 aaStmwBy1: mr. r28,r28 ; Do we have any trailing bytes?
764 beq+ aaStmwSt ; Nope...
766 lwzx r5,r19,r18 ; Yes, pick up one extra register
768 aaStmwSt: crset cr0_eq ; Set this to see if we failed
769 mtmsr r22 ; Flip DR, RI, and maybe PR on
772 beq- cr2,aaStmwBy2 ; No words, check trailing bytes...
774 stw r2,0(r16) ; Save first word
775 bf- cr0_eq,aaStmwDn ; Read failed, escape...
776 addi r16,r16,4 ; Bump sink
777 blt cr1,aaStmwBy2 ; We only had one, we are done...
779 stw r15,0(r16) ; Save second word
780 bf- cr0_eq,aaStmwDn ; Read failed, escape...
781 addi r16,r16,4 ; Bump sink
782 beq cr1,aaStmwBy2 ; We had two, we are done...
784 stw r14,0(r16) ; Save third word
785 addi r16,r16,4 ; Bump sink
787 aaStmwBy2: rlwinm r2,r5,8,24,31 ; Get byte 0
788 cmplwi cr2,r28,0 ; Any trailing bytes to do?
789 rlwinm r14,r5,24,24,31 ; Get byte 3
790 li r8,0 ; Clear second trailing byte
791 cmplwi cr1,r28,2 ; Check for 1, 2, or 3
792 li r9,0 ; Clear third trailing byte
793 beq+ cr2,aaStmwDn ; No trailing bytes...
794 rlwinm r15,r5,16,24,31 ; Get byte 1
796 stb r2,0(r16) ; Save first byte
797 bf- cr0_eq,aaStmwDn ; Read failed, escape...
798 blt cr1,aaStmwDn ; We only had one, we are done...
800 stb r15,1(r16) ; Save second byte
801 bf- cr0_eq,aaStmwDn ; Read failed, escape...
802 beq cr1,aaStmwDn ; We had two, we are done...
804 stb r14,2(r16) ; Save third byte
806 aaStmwDn: mr r4,r0 ; Remember DAR, jus in case we failed the access
807 mr r3,r30 ; Set the normal MSR
808 li r0,loadMSR ; Set the magic "get back to supervisor" SC
809 sc ; Get back to supervisor state
811 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
813 b aaComExit ; We are done....
817 ; Load String Indexed
822 aaLswx: lwz r17,savexer(r13) ; Pick up the XER
823 crclr iUpdate ; Make sure we think this the load form
824 rlwinm. r25,r17,0,25,31 ; Get the number of bytes to load
825 rlwinm r28,r17,0,30,31 ; Get the number of bytes past an even word
826 beq- aaComExit ; Do nothing if 0 length...
827 xor r17,r25,r28 ; Round down to an even word boundary
828 b aaLSComm ; Join up with common load/store code...
832 ; Load String Immediate
837 aaLswi: mr r9,r23 ; Save the DAR
838 bl eIFetch ; Get the instruction image
839 bne- eRedriveAsISI ; Go redrive this as an ISI...
840 rlwinm r25,r10,21,27,31 ; Get the number of bytes to load
841 crclr iUpdate ; Make sure we think this the load form
842 subi r25,r25,1 ; Back off by 1
843 rlwinm r25,r25,0,27,31 ; Clear back down
844 addi r25,r25,1 ; Add back the 1 to convert 0 to 32
845 rlwinm r28,r25,0,30,31 ; Get the number of bytes past an even word
846 xor r17,r25,r28 ; Round down to an even word boundary
847 mr r23,r9 ; Move back the DAR
848 b aaLSComm ; Join up with common load/store code...
851 ; Store String Indexed
856 aaStswx: lwz r17,savexer(r13) ; Pick up the XER
857 crclr iUpdate ; Make sure this is clear in case we have 0 length
858 rlwinm. r25,r17,0,25,31 ; Get the number of bytes to load
859 rlwinm r28,r17,0,30,31 ; Get the number of bytes past an even word
860 beq- aaComExit ; Do nothing if 0 length...
861 xor r17,r25,r28 ; Round down to an even word boundary
862 crset iUpdate ; Make sure we think this the store form
863 b aaLSComm ; Join up with common load/store code...
867 ; Store String Immediate
872 aaStswi: mr r9,r23 ; Save the DAR
873 bl eIFetch ; Get the instruction image
874 bne- eRedriveAsISI ; Go redrive this as an ISI...
875 rlwinm r25,r10,21,27,31 ; Get the number of bytes to load
876 crclr iUpdate ; Make sure we think this the load form
877 subi r25,r25,1 ; Back off by 1
878 rlwinm r25,r25,0,27,31 ; Clear back down
879 addi r25,r25,1 ; Add back the 1 to convert 0 to 32
880 rlwinm r28,r25,21,30,31 ; Get the number of bytes past an even word
881 xor r17,r25,r28 ; Round down to an even word boundary
882 mr r23,r9 ; Move back the DAR
883 b aaLSComm ; Join up with common load/store code...
887 ; Load byte-reversed word
893 add r18,r18,r13 ; Index to source register
894 li r25,4 ; Set the length
896 bfl+ kernAccess,aaSetSegs ; Go set SRs if we are in user and need to
898 crset cr0_eq ; Set this to see if we failed
899 mr r3,r30 ; Set the normal MSR
900 mtmsr r22 ; Flip DR, RI, and maybe PR on
903 lwz r11,0(r23) ; Load the word
905 mr r4,r0 ; Save the DAR if we failed the access
906 li r0,loadMSR ; Set the magic "get back to supervisor" SC
907 sc ; Get back to supervisor state
909 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
911 rlwinm r10,r11,8,0,31 ; Get byte 0 to 3 and byte 2 to 1
912 rlwimi r10,r11,24,16,23 ; Move byte 1 to byte 2
913 rlwimi r10,r11,24,0,7 ; Move byte 3 to byte 0
915 stw r10,saver0(r18) ; Set the register
917 b aaComExit ; All done, go exit...
922 ; Store byte-reversed word
928 add r18,r18,r13 ; Index to source register
929 li r25,4 ; Set the length
930 lwz r11,saver0(r18) ; Get the register to store
932 rlwinm r10,r11,8,0,31 ; Get byte 0 to 3 and byte 2 to 1
933 rlwimi r10,r11,24,16,23 ; Move byte 1 to byte 2
934 rlwimi r10,r11,24,0,7 ; Move byte 3 to byte 0
936 bfl+ kernAccess,aaSetSegs ; Go set SRs if we are in user and need to
938 crset cr0_eq ; Set this to see if we failed
939 mr r3,r30 ; Set the normal MSR
940 mtmsr r22 ; Flip DR, RI, and maybe PR on
943 stw r10,0(r23) ; Store the reversed halfword
945 mr r4,r0 ; Save the DAR if we failed the access
946 li r0,loadMSR ; Set the magic "get back to supervisor" SC
947 sc ; Get back to supervisor state
949 bt+ cr0_eq,aaComExit ; All done, go exit...
950 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
955 ; Load byte-reversed halfword
961 add r18,r18,r13 ; Index to source register
962 li r25,2 ; Set the length
964 bfl+ kernAccess,aaSetSegs ; Go set SRs if we are in user and need to
966 crset cr0_eq ; Set this to see if we failed
967 mr r3,r30 ; Set the normal MSR
968 mtmsr r22 ; Flip DR, RI, and maybe PR on
971 lhz r11,0(r23) ; Load the halfword
973 mr r4,r0 ; Save the DAR if we failed the access
974 li r0,loadMSR ; Set the magic "get back to supervisor" SC
975 sc ; Get back to supervisor state
977 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
979 rlwinm r10,r11,8,16,23 ; Rotate bottom byte up one and clear everything else
980 rlwimi r10,r11,24,24,31 ; Put old second from bottom into bottom
982 stw r10,saver0(r18) ; Set the register
984 b aaComExit ; All done, go exit...
988 ; Store byte-reversed halfword
994 add r18,r18,r13 ; Index to source register
995 li r25,2 ; Set the length
996 lwz r10,saver0(r18) ; Get the register to store
997 rlwinm r10,r10,8,0,31 ; Rotate bottom byte up one
998 rlwimi r10,r10,16,24,31 ; Put old second from bottom into bottom
1000 bfl+ kernAccess,aaSetSegs ; Go set SRs if we are in user and need to
1002 crset cr0_eq ; Set this to see if we failed
1003 mr r3,r30 ; Set the normal MSR
1004 mtmsr r22 ; Flip DR, RI, and maybe PR on
1007 sth r10,0(r23) ; Store the reversed halfword
1009 mr r4,r0 ; Save the DAR if we failed the access
1010 li r0,loadMSR ; Set the magic "get back to supervisor" SC
1011 sc ; Get back to supervisor state
1013 bt+ cr0_eq,aaComExit ; All done, go exit...
1014 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
1017 ; Data cache block zero
1023 li r25,32 ; Set the length
1024 rlwinm r23,r23,0,0,26 ; Round back to a 32-byte boundary
1026 bfl+ kernAccess,aaSetSegs ; Go set SRs if we are in user and need to
1028 crset cr0_eq ; Set this to see if we failed
1029 mr r3,r30 ; Set the normal MSR
1030 li r0,0 ; Clear this out
1031 mtmsr r22 ; Flip DR, RI, and maybe PR on
1034 stw r0,0(r23) ; Clear word
1035 bne- aaDcbzXit ; Got DSI, we are stopping...
1036 stw r0,4(r23) ; Clear word
1037 bne- aaDcbzXit ; Got DSI, we are stopping...
1038 stw r0,8(r23) ; Clear word
1039 bne- aaDcbzXit ; Got DSI, we are stopping...
1040 stw r0,12(r23) ; Clear word
1041 bne- aaDcbzXit ; Got DSI, we are stopping...
1042 stw r0,16(r23) ; Clear word
1043 bne- aaDcbzXit ; Got DSI, we are stopping...
1044 stw r0,20(r23) ; Clear word
1045 bne- aaDcbzXit ; Got DSI, we are stopping...
1046 stw r0,24(r23) ; Clear word
1047 bne- aaDcbzXit ; Got DSI, we are stopping...
1048 stw r0,28(r23) ; Clear word
1050 aaDcbzXit: mr r4,r0 ; Save the DAR if we failed the access
1051 li r0,loadMSR ; Set the magic "get back to supervisor" SC
1052 sc ; Get back to supervisor state
1054 crclr iUpdate ; Make sure we do not think this is an update form
1056 bt+ cr0_eq,aaComExit ; All done, go exit...
1057 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
1061 ; Unhandled alignment exception, pass it along
1065 bfl+ kernAccess,aaUnSetSegs ; Go set SRs if we are in user and need to
1075 ; We go here to emulate a trace exception after we have handled alignment error
1081 bfl+ kernAccess,aaUnSetSegs ; Go set SRs back if we need to because we are not going back to user yet
1082 oris r9,r9,hi16(SAVredrive) ; Set the redrive bit
1083 li r11,T_TRACE ; Set trace interrupt
1084 rlwinm r12,r12,0,16,31 ; Clear top half of SRR1
1085 stw r9,SAVflags(r13) ; Set the flags
1086 stw r11,saveexception(r13) ; Set the exception code
1087 b EXT(EmulExit) ; Exit and do trace interrupt...
1095 mr r20,r1 ; Save the DSISR
1097 bfl+ kernAccess,aaUnSetSegs ; Go set SRs back if we need to because we are not going back to user yet
1098 lwz r4,SAVflags(r13) ; Pick up the flags
1099 li r11,T_DATA_ACCESS ; Set failing data access code
1100 oris r4,r4,hi16(SAVredrive) ; Set the redrive bit
1101 stw r20,savedsisr(r13) ; Set the DSISR of failed access
1102 stw r21,savedar(r13) ; Set the address of the failed access
1103 stw r11,saveexception(r13) ; Set the replacement code
1104 stw r4,SAVflags(r13) ; Set redrive request
1105 b EXT(EmulExit) ; Bail out to handle ISI...
1108 ; Set segment registers for user access. Do not call this if we are trying to get
1109 ; supervisor state memory. We do not need this.
1111 ; Performance-wise, we will usually be setting one SR here. Most memory will be
1112 ; allocated before the 1GB mark. Since the kernel maps the first GB, the exception
1113 ; handler always sets the SRs before we get here. Therefore, we will usually
1116 ; Also, we need to un-do these mapping ONLY if we take a non-standard
1117 ; exit, e.g., emulate DSI, emulate trace exception, etc. This is because
1118 ; translation will never be turned on until we return and at that point,
1119 ; normal exception exit code will restore the first 4 SRs if needed.
1124 .globl EXT(aaSetSegsX)
1128 aaSetSegs: addi r3,r25,-1 ; Point at last accessed offset in range
1129 lwz r7,PP_USERPMAP(r31) ; Get the current user pmap
1130 lis r0,0x4000 ; This is the address of the first segment outside of the kernel
1131 rlwinm r5,r23,6,26,29 ; Get index into pmap table
1132 add r4,r23,r3 ; Point to the last byte accessed
1133 addi r7,r7,PMAP_SEGS ; Point to the segment slot
1134 cmplw r23,r0 ; See if first segment register needs to be reloaded
1135 cmplw cr2,r4,r0 ; Do we need to set the second (if any) SR?
1136 xor r0,r4,r23 ; See if we are in the same segment as first
1137 bge aaSetS1ok ; Nope, we are in a pure user range
1139 lwzx r6,r5,r7 ; Get the user address space SR value
1140 mtsrin r6,r23 ; Load the corresponding SR register
1142 aaSetS1ok: rlwinm. r0,r0,0,0,3 ; Any change in segment?
1143 bgelr- cr2 ; We are in user only space, we do not need to mess with SR
1144 rlwinm r5,r4,6,26,29 ; Get index into pmap table
1145 beqlr+ ; No change in segment, we are done...
1147 lwzx r6,r5,r7 ; Get the user address space SR value
1148 mtsrin r6,r4 ; Load the corresponding SR register
1152 ; Unset segment registers for user access. Do not call unless we had a user access.
1157 .globl EXT(aaUnSetSegsX)
1162 addi r3,r25,-1 ; Point at last accessed offset in range
1163 lis r0,0x4000 ; This is the address of the first segment outside of the kernel
1164 lis r5,hi16(KERNEL_SEG_REG0_VALUE) ; Get the high half of the kernel SR0 value
1165 add r4,r23,r3 ; Point to the last byte accessed
1166 cmplw r23,r0 ; See if first segment register needs to be reloaded
1167 rlwimi r5,r23,24,8,11 ; Make the correct kernel segment
1168 cmplw cr2,r4,r0 ; Do we need to set the second (if any) SR?
1169 xor r0,r4,r23 ; See if we are in the same segment as first
1170 bge aaUnSetS1ok ; Nope, we are in a pure user range
1172 mtsrin r5,r23 ; Load the corresponding SR register
1175 rlwinm. r0,r0,0,0,3 ; Any change in segment?
1176 bgelr cr2 ; We are in user only space, we do not need to mess with SR
1177 rlwimi r5,r4,24,8,11 ; Make the correct kernel segment
1178 beqlr+ ; No change in segment, we are done...
1180 mtsrin r5,r4 ; Load the corresponding SR register
1186 ; Table of functions to load or store floating point registers
1187 ; This table is indexed reg||size||dir. That means that each
1188 ; like load/store pair (e.g., lfd f31/stfd f31) are within the same
1189 ; quadword, which is the current ifetch size. We expect most of the
1190 ; unaligned accesses to be part of copies, therefore, with this
1191 ; organization, we will save the ifetch of the store after the load.
1194 .align 10 ; Make sure we are on a 1k boundary
1197 lfs f0,emfp0(r31) ; Load single variant
1200 stfs f0,emfp0(r31) ; Store single variant
1203 lfd f0,emfp0(r31) ; Load double variant
1206 stfd f0,emfp0(r31) ; Store double variant
1209 lfs f1,emfp0(r31) ; Load single variant
1212 stfs f1,emfp0(r31) ; Store single variant
1215 lfd f1,emfp0(r31) ; Load double variant
1218 stfd f1,emfp0(r31) ; Store double variant
1221 lfs f2,emfp0(r31) ; Load single variant
1224 stfs f2,emfp0(r31) ; Store single variant
1227 lfd f2,emfp0(r31) ; Load double variant
1230 stfd f2,emfp0(r31) ; Store double variant
1233 lfs f3,emfp0(r31) ; Load single variant
1236 stfs f3,emfp0(r31) ; Store single variant
1239 lfd f3,emfp0(r31) ; Load double variant
1242 stfd f3,emfp0(r31) ; Store double variant
1245 lfs f4,emfp0(r31) ; Load single variant
1248 stfs f4,emfp0(r31) ; Store single variant
1251 lfd f4,emfp0(r31) ; Load double variant
1254 stfd f4,emfp0(r31) ; Store double variant
1257 lfs f5,emfp0(r31) ; Load single variant
1260 stfs f5,emfp0(r31) ; Store single variant
1263 lfd f5,emfp0(r31) ; Load double variant
1266 stfd f5,emfp0(r31) ; Store double variant
1269 lfs f6,emfp0(r31) ; Load single variant
1272 stfs f6,emfp0(r31) ; Store single variant
1275 lfd f6,emfp0(r31) ; Load double variant
1278 stfd f6,emfp0(r31) ; Store double variant
1281 lfs f7,emfp0(r31) ; Load single variant
1284 stfs f7,emfp0(r31) ; Store single variant
1287 lfd f7,emfp0(r31) ; Load double variant
1290 stfd f7,emfp0(r31) ; Store double variant
1293 lfs f8,emfp0(r31) ; Load single variant
1296 stfs f8,emfp0(r31) ; Store single variant
1299 lfd f8,emfp0(r31) ; Load double variant
1302 stfd f8,emfp0(r31) ; Store double variant
1305 lfs f9,emfp0(r31) ; Load single variant
1308 stfs f9,emfp0(r31) ; Store single variant
1311 lfd f9,emfp0(r31) ; Load double variant
1314 stfd f9,emfp0(r31) ; Store double variant
1317 lfs f10,emfp0(r31) ; Load single variant
1320 stfs f10,emfp0(r31) ; Store single variant
1323 lfd f10,emfp0(r31) ; Load double variant
1326 stfd f10,emfp0(r31) ; Store double variant
1329 lfs f11,emfp0(r31) ; Load single variant
1332 stfs f11,emfp0(r31) ; Store single variant
1335 lfd f11,emfp0(r31) ; Load double variant
1338 stfd f11,emfp0(r31) ; Store double variant
1341 lfs f12,emfp0(r31) ; Load single variant
1344 stfs f12,emfp0(r31) ; Store single variant
1347 lfd f12,emfp0(r31) ; Load double variant
1350 stfd f12,emfp0(r31) ; Store double variant
1353 lfs f13,emfp0(r31) ; Load single variant
1356 stfs f13,emfp0(r31) ; Store single variant
1359 lfd f13,emfp0(r31) ; Load double variant
1362 stfd f13,emfp0(r31) ; Store double variant
1365 lfs f14,emfp0(r31) ; Load single variant
1368 stfs f14,emfp0(r31) ; Store single variant
1371 lfd f14,emfp0(r31) ; Load double variant
1374 stfd f14,emfp0(r31) ; Store double variant
1377 lfs f15,emfp0(r31) ; Load single variant
1380 stfs f15,emfp0(r31) ; Store single variant
1383 lfd f15,emfp0(r31) ; Load double variant
1386 stfd f15,emfp0(r31) ; Store double variant
1389 lfs f16,emfp0(r31) ; Load single variant
1392 stfs f16,emfp0(r31) ; Store single variant
1395 lfd f16,emfp0(r31) ; Load double variant
1398 stfd f16,emfp0(r31) ; Store double variant
1401 lfs f17,emfp0(r31) ; Load single variant
1404 stfs f17,emfp0(r31) ; Store single variant
1407 lfd f17,emfp0(r31) ; Load double variant
1410 stfd f17,emfp0(r31) ; Store double variant
1413 lfs f18,emfp0(r31) ; Load single variant
1416 stfs f18,emfp0(r31) ; Store single variant
1419 lfd f18,emfp0(r31) ; Load double variant
1422 stfd f18,emfp0(r31) ; Store double variant
1425 lfs f19,emfp0(r31) ; Load single variant
1428 stfs f19,emfp0(r31) ; Store single variant
1431 lfd f19,emfp0(r31) ; Load double variant
1434 stfd f19,emfp0(r31) ; Store double variant
1437 lfs f20,emfp0(r31) ; Load single variant
1440 stfs f20,emfp0(r31) ; Store single variant
1443 lfd f20,emfp0(r31) ; Load double variant
1446 stfd f20,emfp0(r31) ; Store double variant
1449 lfs f21,emfp0(r31) ; Load single variant
1452 stfs f21,emfp0(r31) ; Store single variant
1455 lfd f21,emfp0(r31) ; Load double variant
1458 stfd f21,emfp0(r31) ; Store double variant
1461 lfs f22,emfp0(r31) ; Load single variant
1464 stfs f22,emfp0(r31) ; Store single variant
1467 lfd f22,emfp0(r31) ; Load double variant
1470 stfd f22,emfp0(r31) ; Store double variant
1473 lfs f23,emfp0(r31) ; Load single variant
1476 stfs f23,emfp0(r31) ; Store single variant
1479 lfd f23,emfp0(r31) ; Load double variant
1482 stfd f23,emfp0(r31) ; Store double variant
1485 lfs f24,emfp0(r31) ; Load single variant
1488 stfs f24,emfp0(r31) ; Store single variant
1491 lfd f24,emfp0(r31) ; Load double variant
1494 stfd f24,emfp0(r31) ; Store double variant
1497 lfs f25,emfp0(r31) ; Load single variant
1500 stfs f25,emfp0(r31) ; Store single variant
1503 lfd f25,emfp0(r31) ; Load double variant
1506 stfd f25,emfp0(r31) ; Store double variant
1509 lfs f26,emfp0(r31) ; Load single variant
1512 stfs f26,emfp0(r31) ; Store single variant
1515 lfd f26,emfp0(r31) ; Load double variant
1518 stfd f26,emfp0(r31) ; Store double variant
1521 lfs f27,emfp0(r31) ; Load single variant
1524 stfs f27,emfp0(r31) ; Store single variant
1527 lfd f27,emfp0(r31) ; Load double variant
1530 stfd f27,emfp0(r31) ; Store double variant
1533 lfs f28,emfp0(r31) ; Load single variant
1536 stfs f28,emfp0(r31) ; Store single variant
1539 lfd f28,emfp0(r31) ; Load double variant
1542 stfd f28,emfp0(r31) ; Store double variant
1545 lfs f29,emfp0(r31) ; Load single variant
1548 stfs f29,emfp0(r31) ; Store single variant
1551 lfd f29,emfp0(r31) ; Load double variant
1554 stfd f29,emfp0(r31) ; Store double variant
1557 lfs f30,emfp0(r31) ; Load single variant
1560 stfs f30,emfp0(r31) ; Store single variant
1563 lfd f30,emfp0(r31) ; Load double variant
1566 stfd f30,emfp0(r31) ; Store double variant
1569 lfs f31,emfp0(r31) ; Load single variant
1572 stfs f31,emfp0(r31) ; Store single variant
1575 lfd f31,emfp0(r31) ; Load double variant
1578 stfd f31,emfp0(r31) ; Store double variant