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.
34 #include <ppc/proc_reg.h>
35 #include <ppc/exception.h>
36 #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.
68 mfsprg r31,0 ; Get the per_proc
69 lis r30,hi16(EXT(dgWork)) ; Get the high half of diagnostic work area
70 lwz r12,savesrr1(r13) ; Get the exception info
71 ori r30,r30,lo16(EXT(dgWork)) ; And the low half
72 rlwinm. r0,r12,0,SRR1_PRG_ILL_INS_BIT,SRR1_PRG_ILL_INS_BIT ; Emulation candidate?
73 lwz r30,dgFlags(r30) ; 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,18,25,29 ; Extract index to rA to build EA
115 rlwinm r22,r10,23,25,29 ; Extract index to rB
116 addi r24,r13,saver0 ; 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,18,25,29 ; Extract index to rA to build EA
132 addi r24,r13,saver0 ; 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(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(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(r13) ; Get instruction address
163 crmove kernAccess,cr0_eq ; Remember if fault was in kernel
164 li r25,4 ; Set access length
165 or r22,r22,r30 ; Add PR to access MSR
167 bfl+ kernAccess,aaSetSegs ; Go set SRs if we are in user and need to
169 ori r22,r22,lo16(MASK(MSR_DR)|MASK(MSR_RI)) ; Set RI onto access MSR
171 crset cr0_eq ; Set this to see if we failed
172 mtmsr r22 ; Flip DR, RI, and maybe PR on
175 lwz r10,0(r23) ; Fetch the instruction
177 crmove 28,cr0_eq ; Remember if we failed
178 li r0,loadMSR ; Set the magic "get back to supervisor" SC
179 mr r3,r30 ; Get MSR to load
180 sc ; Get back to supervisor state
182 bfl+ kernAccess,aaUnSetSegs ; Go set SRs if we are in user and need to
184 mtlr r28 ; Restore the LR
185 crmove cr0_eq,28 ; Set CR0_EQ if the fetch succeeded
186 blr ; Return with instruction image in R10
194 lwz r6,savesrr1(r13) ; Get the srr1 value
195 lwz r4,SAVflags(r13) ; Pick up the flags
196 li r11,T_INSTRUCTION_ACCESS ; Set failing instruction fetch code
197 rlwimi r6,r1,0,0,4 ; Move the DSISR bits to the SRR1
198 oris r4,r4,hi16(SAVredrive) ; Set the redrive bit
199 stw r11,saveexception(r13) ; Set the replacement code
200 stw r4,SAVflags(r13) ; Set redrive request
201 stw r6,savesrr1(r13) ; Set the srr1 value
202 b EXT(EmulExit) ; Bail out to handle ISI...
206 ; This code emulates instructions that have failed because of operand
207 ; alignment. We decode the DSISR to figure out what we need to do.
210 ; 0001FC00 - Instruction designation
220 ; 000003E0 - Target/Source register
221 ; 0000001F - Register to update if update form
225 .globl EXT(AlignAssist)
230 b EXT(EmulExit) ; Just return for now...
234 mfsprg r31,0 ; Get the per_proc
235 lwz r20,savedsisr(r13) ; Get the DSISR
236 lwz r21,spcFlags(r31) ; Grab the special flags
237 mtcrf 0x1C,r20 ; Put instruction ID in CR for later
238 rlwinm. r0,r21,0,runningVMbit,runningVMbit ; Are we running a VM?
239 lwz r22,savesrr1(r13) ; Get the SRR1
240 bne- aaPassAlong ; We are in a VM, no emulation for alignment exceptions...
241 rlwinm. r0,r21,0,trapUnalignbit,trapUnalignbit ; Should we trap alignment exceptions?
242 crxor iFloat,iOptype1,iOptype2 ; Set this to 0 if both bits are either 0 or 1
243 mr r26,r20 ; Save the DSISR
244 bne- aaPassAlong ; No alignment exceptions allowed...
245 rlwinm. r0,r22,0,MSR_SE_BIT,MSR_SE_BIT ; Were we single stepping?
246 lwz r23,savedar(r13) ; Pick up the address that we want to access
247 crnot traceInst,cr0_eq ; Remember if trace is on
248 rlwinm. r0,r21,0,notifyUnalignbit,notifyUnalignbit ; Should we notify that an alignment exception happened?
249 mfsprg r28,2 ; Get the processor features
250 crnot iNotify,cr0_eq ; Remember to tell someone we did this
251 rlwinm. r22,r22,0,MSR_PR_BIT,MSR_PR_BIT ; Did we take the exception in the kernel and isolate PR?
252 mfmsr r30 ; Save the MSR for now
253 li r29,emfp0 ; Point to work area
254 crxor iFloat,iFloat,iOptype3 ; Set true if we have a floating point instruction
255 or r22,r22,r30 ; Add PR to access MSR
256 dcbz r29,r31 ; Clear and allocate a cache line for us to work in
257 rlwinm r24,r20,2,25,29 ; Get displacement to register to update if update form
258 rlwimi r20,r20,24,28,28 ; Move load/store indication to the bottom of index
259 ori r22,r22,lo16(MASK(MSR_DR)|MASK(MSR_RI)) ; Set RI onto access MSR
260 crmove kernAccess,cr0_eq ; Remember if fault was in kernel
261 rlwinm. r28,r28,0,pfAltivecb,pfAltivecb ; Do we have Altivec on this machine?
262 rlwimi r20,r20,26,27,27 ; Move single/double indication to just above the bottom
263 beq aaNoVect ; Nope, no Altivec...
265 dssall ; We need to kill streams because we are going to flip to problem state
268 aaNoVect: lis r29,hi16(aaFPopTable) ; High part of FP branch table
269 bf- iFloat,aaNotFloat ; This is not a floating point instruction...
270 li r25,8 ; Assume 8-byte access for now
271 ori r29,r29,lo16(aaFPopTable) ; Low part of FP branch table
272 bt iDouble,aaFPis8 ; So far, we think we are a double...
273 li r25,4 ; Set word access
275 aaFPis8: rlwimi r29,r20,0,22,28 ; Index into table based upon register||iDouble||iStore
276 ori r0,r30,lo16(MASK(MSR_FP)) ; Turn on floating point
277 mtctr r29 ; Get set to call the function
278 bt iStore,aaFPstore ; This is an FP store...
281 ; Here we handle floating point loads
284 aaFPload: bfl+ kernAccess,aaSetSegs ; Go set SRs if we are in user and need to
286 crset cr0_eq ; Set this to see if we failed
287 ori r3,r30,lo16(MASK(MSR_FP)) ; We will need FP on in a bit, so turn on when we ditch problem state
288 mtmsr r22 ; Flip DR, RI, and maybe PR on
291 lwz r10,0(r23) ; Get the first word
292 bf- cr0_eq,aaLdNotDbl ; Jump out if we DSIed...
293 bf iDouble,aaLdNotDbl ; this is not a double...
294 lwz r11,4(r23) ; Get the second half
296 aaLdNotDbl: mr r4,r0 ; Save the DAR if we failed the access
297 li r0,loadMSR ; Set the magic "get back to supervisor" SC
298 sc ; Get back to supervisor state and turn on FP
300 bf- cr0_eq,aaRedriveAsDSI ; Go redrive this as a DSI...
302 stw r10,emfp0(r31) ; Save the first half
303 stw r11,emfp0+4(r31) ; Save the second half, just in case we need it
305 bctrl ; Go set the target FP register
307 b aaComExit ; All done, go exit...
310 ; Here we handle floating point stores
315 aaFPstore: mtmsr r0 ; We need floating point on for the first phase
318 bctrl ; Go save the source FP register
320 lwz r10,emfp0(r31) ; Get first word
321 crandc iDouble,iDouble,iOptype4 ; Change to 4-byte access if stfiwx
322 lwz r11,emfp0+4(r31) ; and the second
323 bf+ iOptype4,aaNotstfiwx ; This is not a stfiwx...
324 li r25,4 ; Set this is a word
325 mr r10,r11 ; The stfiwx wants to store the second half
328 bfl+ kernAccess,aaSetSegs ; Go set SRs if we are in user and need to
330 crset cr0_eq ; Set this to see if we failed
331 mr r3,r30 ; Set the normal MSR
332 mtmsr r22 ; Flip DR, RI, and maybe PR on
335 stw r10,0(r23) ; Save the first word
336 bf- cr0_eq,aaStNotDbl ; Jump out if we DSIed...
337 bf iDouble,aaStNotDbl ; this is not a double...
338 stw r11,4(r23) ; Save the second half
340 aaStNotDbl: mr r4,r0 ; Save the DAR if we failed the access
341 li r0,loadMSR ; Set the magic "get back to supervisor" SC
342 sc ; Get back to supervisor state
345 bf- cr0_eq,aaRedriveAsDSI ; Go redrive this as a DSI...
350 ; Common exit routines
353 aaComExit: lwz r10,savesrr0(r13) ; Get the failing instruction address
354 add r24,r24,r13 ; Offset to update register
355 li r11,T_IN_VAIN ; Assume we are all done
356 addi r10,r10,4 ; Step to the next instruction
357 bf iUpdate,aaComExNU ; Skip if not an update form...
358 stw r23,saver0(r24) ; Update the target
360 aaComExNU: lwz r9,SAVflags(r13) ; Get the flags
361 stw r10,savesrr0(r13) ; Set new PC
362 bt- traceInst,aaComExitrd ; We are tracing, go emulate trace...
363 bf+ iNotify,aaComExGo ; Nothing special here, go...
365 bfl+ kernAccess,aaUnSetSegs ; Go set SRs if we are in user and need to
367 li r11,T_ALIGNMENT ; Set the we just did an alignment exception....
369 aaComExGo: b EXT(EmulExit) ; We are done, no tracing on...
373 ; This is not a floating point operation
375 ; The emulation routines for these are positioned every 64 bytes (16 instructions)
376 ; in a 1024-byte aligned table. It is indexed by taking the low order 4 bits of
377 ; the instruction code in the DSISR and subtracting 7. If this comes up negative,
378 ; the instruction is not to be emulated. Then we add bit 0 of the code * 4. This
379 ; gives us a fairly compact and almost unique index. Both lwm and stmw map to 0 so
380 ; that one needs to be further reduced, and we end up with holes at index 6, 8, and 10.
382 ; If the emulation routine takes more than 16 instructions, it must branch elsewhere
389 lis r19,hi16(aaEmTable) ; Point to high part of table address
390 rlwinm r3,r26,24,26,29 ; Isolate last 4 bits of op type * 4
391 rlwimi r19,r26,20,27,27 ; Get bit 0 of instruction code * 4 into bottom of table base
392 addic. r3,r3,-28 ; Subtract 7*4 to adjust index
393 ori r19,r19,lo16(aaEmTable) ; Low part of table address
394 blt- aaPassAlong ; We do not handle any of these (lwarx, stwcx., eciwx, ecowx)...
395 add r19,r19,r3 ; Point to emulation routine
396 rlwinm r18,r26,29,25,29 ; Get the target/source register displacement
398 mtctr r19 ; Set the routine address
400 bctr ; Go emulate the instruction...
403 ; This is the table of non-floating point emulation routines.
404 ; It is indexed by low 4 bits of DSISR op type - 7 + bit 0 of
411 b aaLmwStmw ; This for lmw/stmw
412 b aaLswx ; This for lwwx
413 b aaLswi ; This for lswi
414 b aaStswx ; This for stswx
415 b aaStswi ; This for stswi
416 b aaLwbrx ; This for lwbrx
417 b aaPassAlong ; This an invalid index (6)
418 b aaStwbrx ; This for stwbrx
419 b aaPassAlong ; This an invalid index (8)
420 b aaLhbrx ; This for lhbrx
421 b aaPassAlong ; This an invalid index (A)
422 b aaSthbrx ; This for sthbrx
423 b aaDcbz ; This for dcbz
424 b aaPassAlong ; This an invalid index (D)
425 b aaPassAlong ; This an invalid index (E)
426 b aaPassAlong ; This an invalid index (F)
430 ; Here we handle the set up for the lmw and stmw. After that, we split off to the
431 ; individual routines.
433 ; Note also that after some set up, all of the string instructions come through here as well.
438 subfic r25,r18,32*4 ; Calculate the length of the transfer
439 li r28,0 ; Set no extra bytes to move (used for string instructions)
440 mr r17,r25 ; Save the word transfer length here
442 aaLSComm: addi r19,r13,saver0 ; Offset to registers in savearea
443 mr r16,r23 ; Make a hunk pointer
445 bfl+ kernAccess,aaSetSegs ; Go set SRs if we are in user and need to
447 bt iUpdate,aaStmw ; This is the stmw...
453 aaLmwNxt: cmplwi cr1,r17,8*4 ; Is there enough to move 8?
454 blt- cr1,aaLmwNxtH ; Not enough for a full hunk...
455 subi r17,r17,8*4 ; Back off for another hunk
457 crset cr0_eq ; Set this to see if we failed
458 mtmsr r22 ; Flip DR, RI, and maybe PR on
461 lwz r2,0(r16) ; Load word 0
462 bf- cr0_eq,aaLmwB1 ; Error, bail...
463 lwz r15,4(r16) ; Load word 1
464 bf- cr0_eq,aaLmwB1 ; Error, bail...
465 lwz r14,8(r16) ; Load word 2
466 bf- cr0_eq,aaLmwB1 ; Error, bail...
467 lwz r5,12(r16) ; Load word 3
468 bf- cr0_eq,aaLmwB1 ; Error, bail...
469 lwz r6,16(r16) ; Load word 4
470 bf- cr0_eq,aaLmwB1 ; Error, bail...
471 lwz r7,20(r16) ; Load word 5
472 bf- cr0_eq,aaLmwB1 ; Error, bail...
473 lwz r8,24(r16) ; Load word 6
474 bf- cr0_eq,aaLmwB1 ; Error, bail...
475 lwz r9,28(r16) ; Load word 7
477 aaLmwB1: mr r4,r0 ; Remember DAR, jus in case we failed the access
478 mr r3,r30 ; Set the normal MSR
479 li r0,loadMSR ; Set the magic "get back to supervisor" SC
480 sc ; Get back to supervisor state
482 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
484 addi r16,r16,8*4 ; Point up to next input aread
486 stwx r2,r19,r18 ; Store register
487 addi r18,r18,4 ; Next register
488 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
489 stwx r15,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 r14,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 r5,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 r6,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 r7,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 r8,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 r9,r19,r18 ; Store register
508 addi r18,r18,4 ; Next register
509 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
511 b aaLmwNxt ; Do the next hunk...
515 aaLmwNxtH: cmplwi cr1,r17,4*4 ; Do we have 4 left?
516 blt cr1,aaLmwL4 ; Nope...
518 subi r17,r17,4*4 ; Set count properly
520 crset cr0_eq ; Set this to see if we failed
521 mtmsr r22 ; Flip DR, RI, and maybe PR on
524 lwz r2,0(r16) ; Load word 0
525 bf- cr0_eq,aaLmwB2 ; Error, bail...
526 lwz r15,4(r16) ; Load word 1
527 bf- cr0_eq,aaLmwB2 ; Error, bail...
528 lwz r14,8(r16) ; Load word 2
529 bf- cr0_eq,aaLmwB2 ; Error, bail...
530 lwz r5,12(r16) ; Load word 3
532 aaLmwB2: mr r4,r0 ; Remember DAR, jus in case we failed the access
533 mr r3,r30 ; Set the normal MSR
534 li r0,loadMSR ; Set the magic "get back to supervisor" SC
535 sc ; Get back to supervisor state
537 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
539 addi r16,r16,4*4 ; Point up to next input aread
541 stwx r2,r19,r18 ; Store register
542 addi r18,r18,4 ; Next register
543 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
544 stwx r15,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 r14,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 r5,r19,r18 ; Store register
551 addi r18,r18,4 ; Next register
552 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
554 aaLmwL4: or. r5,r17,r28 ; Do we have anything left?
555 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three full words left?
556 cmplwi cr2,r17,0 ; Do we have no full words left?
557 beq aaComExit ; Nothing left...
559 crset cr0_eq ; Set this to see if we failed
560 mtmsr r22 ; Flip DR, RI, and maybe PR on
563 beq- cr2,aaLmwBy ; No full words, get bytes...
565 lwz r2,0(r16) ; Pick up first word
566 bf- cr0_eq,aaLmwDn ; Read failed, escape...
567 addi r16,r16,4 ; Next input location
568 blt cr1,aaLmwBy ; We only had one, we are done...
570 lwz r15,0(r16) ; Pick up second word
571 bf- cr0_eq,aaLmwDn ; Read failed, escape...
572 addi r16,r16,4 ; Next input location
573 beq cr1,aaLmwBy ; We had two, we are done...
575 lwz r14,0(r16) ; Load word 3
576 addi r16,r16,4 ; Next input location
578 aaLmwBy: cmplwi cr2,r28,0 ; Any trailing bytes to do?
579 li r8,0 ; Clear second trailing byte
580 cmplwi cr1,r28,2 ; Check for 1, 2, or 3
581 li r9,0 ; Clear third trailing byte
582 beq+ cr2,aaLmwDn ; No trailing bytes...
584 lbz r5,0(r16) ; Pick up first trailing byte
585 bf- cr0_eq,aaLmwDn ; Read failed, escape...
586 blt cr1,aaLmwDn ; We only had one, we are done...
588 lbz r8,1(r16) ; Pick up second trailing byte
589 bf- cr0_eq,aaLmwDn ; Read failed, escape...
590 beq cr1,aaLmwDn ; We had two, we are done...
592 lbz r9,2(r16) ; Get last trailing byte
595 aaLmwDn: rlwinm r5,r5,24,0,7 ; Move first byte to top
596 cmplwi cr2,r17,0 ; Any full words to do?
597 mr r4,r0 ; Remember DAR, just in case we failed the access
598 rlwimi r9,r8,8,16,23 ; Move second byte above third byte
599 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three full words left?
600 mr r3,r30 ; Set the normal MSR
601 rlwimi r5,r9,8,8,23 ; Move bytes 1 and 2 after 0
602 li r0,loadMSR ; Set the magic "get back to supervisor" SC
603 sc ; Get back to supervisor state
605 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
607 beq- cr2,aaLmwCb ; No full words, copy bytes...
609 stwx r2,r19,r18 ; Store register
610 addi r18,r18,4 ; Next register
611 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
612 blt cr1,aaLmwCb ; We only had one, we are done...
614 stwx r15,r19,r18 ; Store register
615 addi r18,r18,4 ; Next register
616 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
617 beq cr1,aaLmwCb ; We had two, we are done...
619 stwx r14,r19,r18 ; Store register
620 addi r18,r18,4 ; Next register
621 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
623 aaLmwCb: mr. r28,r28 ; Any trailing bytes to do?
624 beq+ aaComExit ; Nope, leave...
626 stwx r5,r19,r18 ; Store register
628 b aaComExit ; We are done....
631 ; Store multiple word
637 crclr iUpdate ; Make sure we do not think this is an update form
639 aaStmwNxt: cmplwi cr1,r17,8*4 ; Is there enough to move 8?
640 blt- cr1,aaStmwNxtH ; Not enough for a full hunk...
641 subi r17,r17,8*4 ; Back off for another hunk
643 lwzx r2,r19,r18 ; Store register
644 addi r18,r18,4 ; Next register
645 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
646 lwzx r15,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 r14,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 r5,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 r6,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 r7,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 r8,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 r9,r19,r18 ; Store register
665 addi r18,r18,4 ; Next register
666 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
668 crset cr0_eq ; Set this to see if we failed
669 mtmsr r22 ; Flip DR, RI, and maybe PR on
672 stw r2,0(r16) ; Store word 0
673 bf- cr0_eq,aaStmwB1 ; Error, bail...
674 stw r15,4(r16) ; Store word 1
675 bf- cr0_eq,aaStmwB1 ; Error, bail...
676 stw r14,8(r16) ; Store word 2
677 bf- cr0_eq,aaStmwB1 ; Error, bail...
678 stw r5,12(r16) ; Store word 3
679 bf- cr0_eq,aaStmwB1 ; Error, bail...
680 stw r6,16(r16) ; Store word 4
681 bf- cr0_eq,aaStmwB1 ; Error, bail...
682 stw r7,20(r16) ; Store word 5
683 bf- cr0_eq,aaStmwB1 ; Error, bail...
684 stw r8,24(r16) ; Store word 6
685 bf- cr0_eq,aaStmwB1 ; Error, bail...
686 stw r9,28(r16) ; Store word 7
688 addi r16,r16,8*4 ; Point up to next output aread
691 aaStmwB1: mr r4,r0 ; Remember DAR, jus in case we failed the access
692 mr r3,r30 ; Set the normal MSR
693 li r0,loadMSR ; Set the magic "get back to supervisor" SC
694 sc ; Get back to supervisor state
696 bt- cr0_eq,aaStmwNxt ; We have more to do and no failed access...
697 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
701 aaStmwNxtH: cmplwi cr1,r17,(4*4) ; Do we have at least 4 left?
702 blt cr1,aaStmwL4 ; Nope...
703 subi r17,r17,4*4 ; Set count properly
705 lwzx r2,r19,r18 ; Store register
706 addi r18,r18,4 ; Next register
707 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
708 lwzx r15,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 r14,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 r5,r19,r18 ; Store register
715 addi r18,r18,4 ; Next register
716 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
718 crset cr0_eq ; Set this to see if we failed
719 mtmsr r22 ; Flip DR, RI, and maybe PR on
722 stw r2,0(r16) ; Store word 0
723 bf- cr0_eq,aaStmwB2 ; Error, bail...
724 stw r15,4(r16) ; Store word 1
725 bf- cr0_eq,aaStmwB2 ; Error, bail...
726 stw r14,8(r16) ; Store word 2
727 bf- cr0_eq,aaStmwB2 ; Error, bail...
728 stw r5,12(r16) ; Store word 3
730 addi r16,r16,4*4 ; Point up to next input aread
732 aaStmwB2: mr r4,r0 ; Remember DAR, jus in case we failed the access
733 mr r3,r30 ; Set the normal MSR
734 li r0,loadMSR ; Set the magic "get back to supervisor" SC
735 sc ; Get back to supervisor state
737 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
739 aaStmwL4: or. r5,r17,r28 ; Do we have anything left to do?
740 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three left?
741 cmplwi cr2,r17,0 ; Do we have no full words left?
742 beq aaComExit ; Nothing left...
744 beq- cr2,aaStmwBy1 ; No full words, check out bytes
746 lwzx r2,r19,r18 ; Store register
747 addi r18,r18,4 ; Next register
748 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
749 blt cr1,aaStmwBy1 ; We only had one, go save it...
751 lwzx r15,r19,r18 ; Store register
752 addi r18,r18,4 ; Next register
753 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
754 beq cr1,aaStmwBy1 ; We had two, go save it...
756 lwzx r14,r19,r18 ; Store register
757 addi r18,r18,4 ; Next register
758 rlwinm r18,r18,0,25,29 ; Wrap back to 0 if needed
760 aaStmwBy1: mr. r28,r28 ; Do we have any trailing bytes?
761 beq+ aaStmwSt ; Nope...
763 lwzx r5,r19,r18 ; Yes, pick up one extra register
765 aaStmwSt: crset cr0_eq ; Set this to see if we failed
766 mtmsr r22 ; Flip DR, RI, and maybe PR on
769 beq- cr2,aaStmwBy2 ; No words, check trailing bytes...
771 stw r2,0(r16) ; Save first word
772 bf- cr0_eq,aaStmwDn ; Read failed, escape...
773 addi r16,r16,4 ; Bump sink
774 blt cr1,aaStmwBy2 ; We only had one, we are done...
776 stw r15,0(r16) ; Save second word
777 bf- cr0_eq,aaStmwDn ; Read failed, escape...
778 addi r16,r16,4 ; Bump sink
779 beq cr1,aaStmwBy2 ; We had two, we are done...
781 stw r14,0(r16) ; Save third word
782 addi r16,r16,4 ; Bump sink
784 aaStmwBy2: rlwinm r2,r5,8,24,31 ; Get byte 0
785 cmplwi cr2,r28,0 ; Any trailing bytes to do?
786 rlwinm r14,r5,24,24,31 ; Get byte 3
787 li r8,0 ; Clear second trailing byte
788 cmplwi cr1,r28,2 ; Check for 1, 2, or 3
789 li r9,0 ; Clear third trailing byte
790 beq+ cr2,aaStmwDn ; No trailing bytes...
791 rlwinm r15,r5,16,24,31 ; Get byte 1
793 stb r2,0(r16) ; Save first byte
794 bf- cr0_eq,aaStmwDn ; Read failed, escape...
795 blt cr1,aaStmwDn ; We only had one, we are done...
797 stb r15,1(r16) ; Save second byte
798 bf- cr0_eq,aaStmwDn ; Read failed, escape...
799 beq cr1,aaStmwDn ; We had two, we are done...
801 stb r14,2(r16) ; Save third byte
803 aaStmwDn: mr r4,r0 ; Remember DAR, jus in case we failed the access
804 mr r3,r30 ; Set the normal MSR
805 li r0,loadMSR ; Set the magic "get back to supervisor" SC
806 sc ; Get back to supervisor state
808 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
810 b aaComExit ; We are done....
814 ; Load String Indexed
819 aaLswx: lwz r17,savexer(r13) ; Pick up the XER
820 crclr iUpdate ; Make sure we think this the load form
821 rlwinm. r25,r17,0,25,31 ; Get the number of bytes to load
822 rlwinm r28,r17,0,30,31 ; Get the number of bytes past an even word
823 beq- aaComExit ; Do nothing if 0 length...
824 xor r17,r25,r28 ; Round down to an even word boundary
825 b aaLSComm ; Join up with common load/store code...
829 ; Load String Immediate
834 aaLswi: mr r9,r23 ; Save the DAR
835 bl eIFetch ; Get the instruction image
836 bne- eRedriveAsISI ; Go redrive this as an ISI...
837 rlwinm r25,r10,21,27,31 ; Get the number of bytes to load
838 crclr iUpdate ; Make sure we think this the load form
839 subi r25,r25,1 ; Back off by 1
840 rlwinm r25,r25,0,27,31 ; Clear back down
841 addi r25,r25,1 ; Add back the 1 to convert 0 to 32
842 rlwinm r28,r25,0,30,31 ; Get the number of bytes past an even word
843 xor r17,r25,r28 ; Round down to an even word boundary
844 mr r23,r9 ; Move back the DAR
845 b aaLSComm ; Join up with common load/store code...
848 ; Store String Indexed
853 aaStswx: lwz r17,savexer(r13) ; Pick up the XER
854 crclr iUpdate ; Make sure this is clear in case we have 0 length
855 rlwinm. r25,r17,0,25,31 ; Get the number of bytes to load
856 rlwinm r28,r17,0,30,31 ; Get the number of bytes past an even word
857 beq- aaComExit ; Do nothing if 0 length...
858 xor r17,r25,r28 ; Round down to an even word boundary
859 crset iUpdate ; Make sure we think this the store form
860 b aaLSComm ; Join up with common load/store code...
864 ; Store String Immediate
869 aaStswi: mr r9,r23 ; Save the DAR
870 bl eIFetch ; Get the instruction image
871 bne- eRedriveAsISI ; Go redrive this as an ISI...
872 rlwinm r25,r10,21,27,31 ; Get the number of bytes to load
873 crclr iUpdate ; Make sure we think this the load form
874 subi r25,r25,1 ; Back off by 1
875 rlwinm r25,r25,0,27,31 ; Clear back down
876 addi r25,r25,1 ; Add back the 1 to convert 0 to 32
877 rlwinm r28,r25,21,30,31 ; Get the number of bytes past an even word
878 xor r17,r25,r28 ; Round down to an even word boundary
879 mr r23,r9 ; Move back the DAR
880 b aaLSComm ; Join up with common load/store code...
884 ; Load byte-reversed word
890 add r18,r18,r13 ; Index to source register
891 li r25,4 ; Set the length
893 bfl+ kernAccess,aaSetSegs ; Go set SRs if we are in user and need to
895 crset cr0_eq ; Set this to see if we failed
896 mr r3,r30 ; Set the normal MSR
897 mtmsr r22 ; Flip DR, RI, and maybe PR on
900 lwz r11,0(r23) ; Load the word
902 mr r4,r0 ; Save the DAR if we failed the access
903 li r0,loadMSR ; Set the magic "get back to supervisor" SC
904 sc ; Get back to supervisor state
906 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
908 rlwinm r10,r11,8,0,31 ; Get byte 0 to 3 and byte 2 to 1
909 rlwimi r10,r11,24,16,23 ; Move byte 1 to byte 2
910 rlwimi r10,r11,24,0,7 ; Move byte 3 to byte 0
912 stw r10,saver0(r18) ; Set the register
914 b aaComExit ; All done, go exit...
919 ; Store byte-reversed word
925 add r18,r18,r13 ; Index to source register
926 li r25,4 ; Set the length
927 lwz r11,saver0(r18) ; Get the register to store
929 rlwinm r10,r11,8,0,31 ; Get byte 0 to 3 and byte 2 to 1
930 rlwimi r10,r11,24,16,23 ; Move byte 1 to byte 2
931 rlwimi r10,r11,24,0,7 ; Move byte 3 to byte 0
933 bfl+ kernAccess,aaSetSegs ; Go set SRs if we are in user and need to
935 crset cr0_eq ; Set this to see if we failed
936 mr r3,r30 ; Set the normal MSR
937 mtmsr r22 ; Flip DR, RI, and maybe PR on
940 stw r10,0(r23) ; Store the reversed halfword
942 mr r4,r0 ; Save the DAR if we failed the access
943 li r0,loadMSR ; Set the magic "get back to supervisor" SC
944 sc ; Get back to supervisor state
946 bt+ cr0_eq,aaComExit ; All done, go exit...
947 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
952 ; Load byte-reversed halfword
958 add r18,r18,r13 ; Index to source register
959 li r25,2 ; Set the length
961 bfl+ kernAccess,aaSetSegs ; Go set SRs if we are in user and need to
963 crset cr0_eq ; Set this to see if we failed
964 mr r3,r30 ; Set the normal MSR
965 mtmsr r22 ; Flip DR, RI, and maybe PR on
968 lhz r11,0(r23) ; Load the halfword
970 mr r4,r0 ; Save the DAR if we failed the access
971 li r0,loadMSR ; Set the magic "get back to supervisor" SC
972 sc ; Get back to supervisor state
974 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
976 rlwinm r10,r11,8,16,23 ; Rotate bottom byte up one and clear everything else
977 rlwimi r10,r11,24,24,31 ; Put old second from bottom into bottom
979 stw r10,saver0(r18) ; Set the register
981 b aaComExit ; All done, go exit...
985 ; Store byte-reversed halfword
991 add r18,r18,r13 ; Index to source register
992 li r25,2 ; Set the length
993 lwz r10,saver0(r18) ; Get the register to store
994 rlwinm r10,r10,8,0,31 ; Rotate bottom byte up one
995 rlwimi r10,r10,16,24,31 ; Put old second from bottom into bottom
997 bfl+ kernAccess,aaSetSegs ; Go set SRs if we are in user and need to
999 crset cr0_eq ; Set this to see if we failed
1000 mr r3,r30 ; Set the normal MSR
1001 mtmsr r22 ; Flip DR, RI, and maybe PR on
1004 sth r10,0(r23) ; Store the reversed halfword
1006 mr r4,r0 ; Save the DAR if we failed the access
1007 li r0,loadMSR ; Set the magic "get back to supervisor" SC
1008 sc ; Get back to supervisor state
1010 bt+ cr0_eq,aaComExit ; All done, go exit...
1011 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
1014 ; Data cache block zero
1020 li r25,32 ; Set the length
1021 rlwinm r23,r23,0,0,26 ; Round back to a 32-byte boundary
1023 bfl+ kernAccess,aaSetSegs ; Go set SRs if we are in user and need to
1025 crset cr0_eq ; Set this to see if we failed
1026 mr r3,r30 ; Set the normal MSR
1027 li r0,0 ; Clear this out
1028 mtmsr r22 ; Flip DR, RI, and maybe PR on
1031 stw r0,0(r23) ; Clear word
1032 bne- aaDcbzXit ; Got DSI, we are stopping...
1033 stw r0,4(r23) ; Clear word
1034 bne- aaDcbzXit ; Got DSI, we are stopping...
1035 stw r0,8(r23) ; Clear word
1036 bne- aaDcbzXit ; Got DSI, we are stopping...
1037 stw r0,12(r23) ; Clear word
1038 bne- aaDcbzXit ; Got DSI, we are stopping...
1039 stw r0,16(r23) ; Clear word
1040 bne- aaDcbzXit ; Got DSI, we are stopping...
1041 stw r0,20(r23) ; Clear word
1042 bne- aaDcbzXit ; Got DSI, we are stopping...
1043 stw r0,24(r23) ; Clear word
1044 bne- aaDcbzXit ; Got DSI, we are stopping...
1045 stw r0,28(r23) ; Clear word
1047 aaDcbzXit: mr r4,r0 ; Save the DAR if we failed the access
1048 li r0,loadMSR ; Set the magic "get back to supervisor" SC
1049 sc ; Get back to supervisor state
1051 crclr iUpdate ; Make sure we do not think this is an update form
1053 bt+ cr0_eq,aaComExit ; All done, go exit...
1054 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
1058 ; Unhandled alignment exception, pass it along
1062 bfl+ kernAccess,aaUnSetSegs ; Go set SRs if we are in user and need to
1072 ; We go here to emulate a trace exception after we have handled alignment error
1078 bfl+ kernAccess,aaUnSetSegs ; Go set SRs back if we need to because we are not going back to user yet
1079 oris r9,r9,hi16(SAVredrive) ; Set the redrive bit
1080 li r11,T_TRACE ; Set trace interrupt
1081 rlwinm r12,r12,0,16,31 ; Clear top half of SRR1
1082 stw r9,SAVflags(r13) ; Set the flags
1083 stw r11,saveexception(r13) ; Set the exception code
1084 b EXT(EmulExit) ; Exit and do trace interrupt...
1092 mr r20,r1 ; Save the DSISR
1094 bfl+ kernAccess,aaUnSetSegs ; Go set SRs back if we need to because we are not going back to user yet
1095 lwz r4,SAVflags(r13) ; Pick up the flags
1096 li r11,T_DATA_ACCESS ; Set failing data access code
1097 oris r4,r4,hi16(SAVredrive) ; Set the redrive bit
1098 stw r20,savedsisr(r13) ; Set the DSISR of failed access
1099 stw r21,savedar(r13) ; Set the address of the failed access
1100 stw r11,saveexception(r13) ; Set the replacement code
1101 stw r4,SAVflags(r13) ; Set redrive request
1102 b EXT(EmulExit) ; Bail out to handle ISI...
1105 ; Set segment registers for user access. Do not call this if we are trying to get
1106 ; supervisor state memory. We do not need this.
1108 ; Performance-wise, we will usually be setting one SR here. Most memory will be
1109 ; allocated before the 1GB mark. Since the kernel maps the first GB, the exception
1110 ; handler always sets the SRs before we get here. Therefore, we will usually
1113 ; Also, we need to un-do these mapping ONLY if we take a non-standard
1114 ; exit, e.g., emulate DSI, emulate trace exception, etc. This is because
1115 ; translation will never be turned on until we return and at that point,
1116 ; normal exception exit code will restore the first 4 SRs if needed.
1121 .globl EXT(aaSetSegsX)
1125 aaSetSegs: addi r3,r25,-1 ; Point at last accessed offset in range
1126 lwz r7,PP_USERPMAP(r31) ; Get the current user pmap
1127 lis r0,0x4000 ; This is the address of the first segment outside of the kernel
1128 rlwinm r5,r23,6,26,29 ; Get index into pmap table
1129 add r4,r23,r3 ; Point to the last byte accessed
1130 addi r5,r5,PMAP_SEGS ; Point to the segment slot
1131 cmplw r23,r0 ; See if first segment register needs to be reloaded
1132 cmplw cr2,r4,r0 ; Do we need to set the second (if any) SR?
1133 xor r0,r4,r23 ; See if we are in the same segment as first
1134 bge aaSetS1ok ; Nope, we are in a pure user range
1136 lwzx r6,r5,r7 ; Get the user address space SR value
1137 mtsrin r6,r23 ; Load the corresponding SR register
1139 aaSetS1ok: rlwinm. r0,r0,0,0,3 ; Any change in segment?
1140 bgelr- cr2 ; We are in user only space, we do not need to mess with SR
1141 rlwinm r5,r4,6,26,29 ; Get index into pmap table
1142 beqlr+ ; No change in segment, we are done...
1144 lwzx r6,r5,r7 ; Get the user address space SR value
1145 mtsrin r6,r4 ; Load the corresponding SR register
1149 ; Unset segment registers for user access. Do not call unless we had a user access.
1154 .globl EXT(aaUnSetSegsX)
1159 addi r3,r25,-1 ; Point at last accessed offset in range
1160 lis r0,0x4000 ; This is the address of the first segment outside of the kernel
1161 lis r5,hi16(KERNEL_SEG_REG0_VALUE) ; Get the high half of the kernel SR0 value
1162 add r4,r23,r3 ; Point to the last byte accessed
1163 cmplw r23,r0 ; See if first segment register needs to be reloaded
1164 rlwimi r5,r23,24,8,11 ; Make the correct kernel segment
1165 cmplw cr2,r4,r0 ; Do we need to set the second (if any) SR?
1166 xor r0,r4,r23 ; See if we are in the same segment as first
1167 bge aaUnSetS1ok ; Nope, we are in a pure user range
1169 mtsrin r5,r23 ; Load the corresponding SR register
1172 rlwinm. r0,r0,0,0,3 ; Any change in segment?
1173 bgelr cr2 ; We are in user only space, we do not need to mess with SR
1174 rlwimi r5,r4,24,8,11 ; Make the correct kernel segment
1175 beqlr+ ; No change in segment, we are done...
1177 mtsrin r5,r4 ; Load the corresponding SR register
1183 ; Table of functions to load or store floating point registers
1184 ; This table is indexed reg||size||dir. That means that each
1185 ; like load/store pair (e.g., lfd f31/stfd f31) are within the same
1186 ; quadword, which is the current ifetch size. We expect most of the
1187 ; unaligned accesses to be part of copies, therefore, with this
1188 ; organization, we will save the ifetch of the store after the load.
1191 .align 10 ; Make sure we are on a 1k boundary
1194 lfs f0,emfp0(r31) ; Load single variant
1197 stfs f0,emfp0(r31) ; Store single variant
1200 lfd f0,emfp0(r31) ; Load double variant
1203 stfd f0,emfp0(r31) ; Store double variant
1206 lfs f1,emfp0(r31) ; Load single variant
1209 stfs f1,emfp0(r31) ; Store single variant
1212 lfd f1,emfp0(r31) ; Load double variant
1215 stfd f1,emfp0(r31) ; Store double variant
1218 lfs f2,emfp0(r31) ; Load single variant
1221 stfs f2,emfp0(r31) ; Store single variant
1224 lfd f2,emfp0(r31) ; Load double variant
1227 stfd f2,emfp0(r31) ; Store double variant
1230 lfs f3,emfp0(r31) ; Load single variant
1233 stfs f3,emfp0(r31) ; Store single variant
1236 lfd f3,emfp0(r31) ; Load double variant
1239 stfd f3,emfp0(r31) ; Store double variant
1242 lfs f4,emfp0(r31) ; Load single variant
1245 stfs f4,emfp0(r31) ; Store single variant
1248 lfd f4,emfp0(r31) ; Load double variant
1251 stfd f4,emfp0(r31) ; Store double variant
1254 lfs f5,emfp0(r31) ; Load single variant
1257 stfs f5,emfp0(r31) ; Store single variant
1260 lfd f5,emfp0(r31) ; Load double variant
1263 stfd f5,emfp0(r31) ; Store double variant
1266 lfs f6,emfp0(r31) ; Load single variant
1269 stfs f6,emfp0(r31) ; Store single variant
1272 lfd f6,emfp0(r31) ; Load double variant
1275 stfd f6,emfp0(r31) ; Store double variant
1278 lfs f7,emfp0(r31) ; Load single variant
1281 stfs f7,emfp0(r31) ; Store single variant
1284 lfd f7,emfp0(r31) ; Load double variant
1287 stfd f7,emfp0(r31) ; Store double variant
1290 lfs f8,emfp0(r31) ; Load single variant
1293 stfs f8,emfp0(r31) ; Store single variant
1296 lfd f8,emfp0(r31) ; Load double variant
1299 stfd f8,emfp0(r31) ; Store double variant
1302 lfs f9,emfp0(r31) ; Load single variant
1305 stfs f9,emfp0(r31) ; Store single variant
1308 lfd f9,emfp0(r31) ; Load double variant
1311 stfd f9,emfp0(r31) ; Store double variant
1314 lfs f10,emfp0(r31) ; Load single variant
1317 stfs f10,emfp0(r31) ; Store single variant
1320 lfd f10,emfp0(r31) ; Load double variant
1323 stfd f10,emfp0(r31) ; Store double variant
1326 lfs f11,emfp0(r31) ; Load single variant
1329 stfs f11,emfp0(r31) ; Store single variant
1332 lfd f11,emfp0(r31) ; Load double variant
1335 stfd f11,emfp0(r31) ; Store double variant
1338 lfs f12,emfp0(r31) ; Load single variant
1341 stfs f12,emfp0(r31) ; Store single variant
1344 lfd f12,emfp0(r31) ; Load double variant
1347 stfd f12,emfp0(r31) ; Store double variant
1350 lfs f13,emfp0(r31) ; Load single variant
1353 stfs f13,emfp0(r31) ; Store single variant
1356 lfd f13,emfp0(r31) ; Load double variant
1359 stfd f13,emfp0(r31) ; Store double variant
1362 lfs f14,emfp0(r31) ; Load single variant
1365 stfs f14,emfp0(r31) ; Store single variant
1368 lfd f14,emfp0(r31) ; Load double variant
1371 stfd f14,emfp0(r31) ; Store double variant
1374 lfs f15,emfp0(r31) ; Load single variant
1377 stfs f15,emfp0(r31) ; Store single variant
1380 lfd f15,emfp0(r31) ; Load double variant
1383 stfd f15,emfp0(r31) ; Store double variant
1386 lfs f16,emfp0(r31) ; Load single variant
1389 stfs f16,emfp0(r31) ; Store single variant
1392 lfd f16,emfp0(r31) ; Load double variant
1395 stfd f16,emfp0(r31) ; Store double variant
1398 lfs f17,emfp0(r31) ; Load single variant
1401 stfs f17,emfp0(r31) ; Store single variant
1404 lfd f17,emfp0(r31) ; Load double variant
1407 stfd f17,emfp0(r31) ; Store double variant
1410 lfs f18,emfp0(r31) ; Load single variant
1413 stfs f18,emfp0(r31) ; Store single variant
1416 lfd f18,emfp0(r31) ; Load double variant
1419 stfd f18,emfp0(r31) ; Store double variant
1422 lfs f19,emfp0(r31) ; Load single variant
1425 stfs f19,emfp0(r31) ; Store single variant
1428 lfd f19,emfp0(r31) ; Load double variant
1431 stfd f19,emfp0(r31) ; Store double variant
1434 lfs f20,emfp0(r31) ; Load single variant
1437 stfs f20,emfp0(r31) ; Store single variant
1440 lfd f20,emfp0(r31) ; Load double variant
1443 stfd f20,emfp0(r31) ; Store double variant
1446 lfs f21,emfp0(r31) ; Load single variant
1449 stfs f21,emfp0(r31) ; Store single variant
1452 lfd f21,emfp0(r31) ; Load double variant
1455 stfd f21,emfp0(r31) ; Store double variant
1458 lfs f22,emfp0(r31) ; Load single variant
1461 stfs f22,emfp0(r31) ; Store single variant
1464 lfd f22,emfp0(r31) ; Load double variant
1467 stfd f22,emfp0(r31) ; Store double variant
1470 lfs f23,emfp0(r31) ; Load single variant
1473 stfs f23,emfp0(r31) ; Store single variant
1476 lfd f23,emfp0(r31) ; Load double variant
1479 stfd f23,emfp0(r31) ; Store double variant
1482 lfs f24,emfp0(r31) ; Load single variant
1485 stfs f24,emfp0(r31) ; Store single variant
1488 lfd f24,emfp0(r31) ; Load double variant
1491 stfd f24,emfp0(r31) ; Store double variant
1494 lfs f25,emfp0(r31) ; Load single variant
1497 stfs f25,emfp0(r31) ; Store single variant
1500 lfd f25,emfp0(r31) ; Load double variant
1503 stfd f25,emfp0(r31) ; Store double variant
1506 lfs f26,emfp0(r31) ; Load single variant
1509 stfs f26,emfp0(r31) ; Store single variant
1512 lfd f26,emfp0(r31) ; Load double variant
1515 stfd f26,emfp0(r31) ; Store double variant
1518 lfs f27,emfp0(r31) ; Load single variant
1521 stfs f27,emfp0(r31) ; Store single variant
1524 lfd f27,emfp0(r31) ; Load double variant
1527 stfd f27,emfp0(r31) ; Store double variant
1530 lfs f28,emfp0(r31) ; Load single variant
1533 stfs f28,emfp0(r31) ; Store single variant
1536 lfd f28,emfp0(r31) ; Load double variant
1539 stfd f28,emfp0(r31) ; Store double variant
1542 lfs f29,emfp0(r31) ; Load single variant
1545 stfs f29,emfp0(r31) ; Store single variant
1548 lfd f29,emfp0(r31) ; Load double variant
1551 stfd f29,emfp0(r31) ; Store double variant
1554 lfs f30,emfp0(r31) ; Load single variant
1557 stfs f30,emfp0(r31) ; Store single variant
1560 lfd f30,emfp0(r31) ; Load double variant
1563 stfd f30,emfp0(r31) ; Store double variant
1566 lfs f31,emfp0(r31) ; Load single variant
1569 stfs f31,emfp0(r31) ; Store single variant
1572 lfd f31,emfp0(r31) ; Load double variant
1575 stfd f31,emfp0(r31) ; Store double variant