2 * Copyright (c) 2000-2007 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
31 Emulate instructions and traps.
33 Lovingly crafted by Bill Angell using traditional methods and only natural or recycled materials.
34 No animal products are used other than rendered otter bile and deep fried pork lard.
39 #include <ppc/proc_reg.h>
40 #include <ppc/exception.h>
41 #include <ppc/cpu_capabilities.h>
42 #include <mach/machine/vm_param.h>
48 ; General stuff what happens here:
49 ; 1) All general context saved, interrupts off, translation off
50 ; 2) Vector and floating point disabled, but there may be live context.
51 ; This code is responsible for saving and restoring what is used. This
52 ; includes exception states, java mode, etc.
53 ; 3) No attempt is made to resolve page faults. PTE misses are handled
54 ; automatically, but actual faults (ala copyin/copyout) are not. If
55 ; a fault does occur, the exception that caused entry to the emulation
56 ; routine is remapped to either an instruction or data miss (depending
57 ; upon the stage detected) and redrived through the exception handler.
58 ; The only time that an instruction fault can happen is when a different
59 ; processor removes a mapping between our original fault and when we
60 ; fetch the assisted instruction. For an assisted instruction, data
61 ; faults should not occur (except in the MP case). For a purely
62 ; emulated instruction, faults can occur.
72 bf-- pf64Bitb,emn64 ; Skip if not 64-bit
73 b EXT(Emulate64) ; Jump to the 64-bit code...
75 emn64: mfsprg r31,0 ; Get the per_proc
76 lwz r12,savesrr1+4(r13) ; Get the exception info
77 rlwinm. r0,r12,0,SRR1_PRG_ILL_INS_BIT,SRR1_PRG_ILL_INS_BIT ; Emulation candidate?
78 lwz r30,dgFlags(0) ; Get the flags
79 beq+ eExit ; Nope, do not try to emulate...
81 rlwinm. r0,r30,0,enaDiagEMb,enaDiagEMb ; Do we want to try to emulate something?
82 mfsprg r28,2 ; Get the processor features
83 beq+ eExit ; No emulation allowed...
85 rlwinm. r28,r28,0,pfAltivecb,pfAltivecb ; Do we have Altivec on this machine?
86 beq eNoVect ; Nope, no Altivec...
88 dssall ; We need to kill streams because we are going to flip to problem state
91 eNoVect: bl eIFetch ; Get the instruction image
92 bne- eRedriveAsISI ; Go redrive this as an ISI...
94 rlwinm. r0,r10,0,0,5 ; See if we have the "special" op code here
95 rlwinm r20,r10,16,22,31 ; Set rS/rD and rA
96 bne+ eExit ; Not special op, ignore...
98 rlwinm r0,r10,31,22,31 ; Extract the sub op code
100 rlwimi r20,r10,14,15,16 ; Move bits 29 and 30 of instruction to 15 and 16 of DSISR
101 cmplwi r0,790 ; lhbrx?
102 rlwimi r20,r10,8,17,17 ; Move bit 25 to bit 17
103 cror cr1_eq,cr1_eq,cr0_eq ; Remember
104 cmplwi r0,534 ; lwbrx?
105 rlwimi r20,r10,3,18,21 ; Move bit 21-24 to bit 18-21
106 cror cr1_eq,cr1_eq,cr0_eq ; Remember
107 cmplwi r0,918 ; sthbrx?
108 cror cr1_eq,cr1_eq,cr0_eq ; Remember
109 cmplwi r0,662 ; stwbrx?
110 cror cr1_eq,cr1_eq,cr0_eq ; Remember
111 cmplwi r0,1014 ; dcbz?
112 cror cr1_eq,cr1_eq,cr0_eq ; Remember
113 cmplwi r0,533 ; lswx?
114 cror cr1_eq,cr1_eq,cr0_eq ; Remember
115 cmplwi r0,661 ; stswx?
116 cror cr1_eq,cr1_eq,cr0_eq ; Remember
117 bne cr1_eq,eNotIndex ; Go check non-index forms...
119 rlwinm. r21,r10,19,24,28 ; Extract index to rA to build EA
120 rlwinm r22,r10,24,24,28 ; Extract index to rB
121 addi r24,r13,saver0+4 ; Point to the start of registers
122 li r19,0 ; Assume 0 base
123 beq eZeroBase ; Yes...
124 lwzx r19,r24,r21 ; Get the base register value
126 eZeroBase: lwzx r22,r24,r22 ; Get the index value
127 add r22,r22,r19 ; Get DAR
128 b eFinishUp ; Done, go finish up...
130 eNotIndex: cmplwi r0,725 ; stswi?
131 cror cr1_eq,cr1_eq,cr0_eq ; Remember
132 cmplwi r0,597 ; lswi?
133 cror cr1_eq,cr1_eq,cr0_eq ; Remember
134 bne cr1,eExit ; Not one we handle...
136 rlwinm. r21,r10,19,24,28 ; Extract index to rA to build EA
137 addi r24,r13,saver0+4 ; Point to the start of registers
138 li r22,0 ; Assume 0 base
139 beq eFinishUp ; Yes, it is...
140 lwzx r22,r24,r21 ; Get the base register value
142 eFinishUp: stw r20,savedsisr(r13) ; Set the DSISR
143 li r11,T_ALIGNMENT ; Get the exception code
144 stw r22,savedar+4(r13) ; Save the DAR
145 stw r11,saveexception(r13) ; Set the exception code
146 b EXT(AlignAssist) ; Go emulate the handler...
149 eExit: b EXT(EmulExit) ; Just return for now...
153 ; Fetch the failing instruction.
154 ; Image returned in R10 if CR0_EQ is false, otherwise, an ISI should be generated.
155 ; R1 has the DSISR if access failed.
160 eIFetch: lwz r23,savesrr1+4(r13) ; Get old MSR
161 mflr r28 ; Save return
163 rlwinm r3,r23,32-MSR_DR_BIT+MSR_IR_BIT,MSR_DR_BIT,MSR_DR_BIT ; Move IR to DR for ifetch
164 mfmsr r30 ; Save the MSR for now
165 rlwimi r3,r23,32-MSR_RI_BIT+MSR_DR_BIT,MSR_RI_BIT,MSR_RI_BIT ; Move DR to RI for ifetch
167 lwz r23,savesrr0+4(r13) ; Get instruction address
168 or r3,r23,r3 ; Turn on the DR and RI bit if translation was on
170 crset cr0_eq ; Set this to see if we failed
171 mtmsr r3 ; Flip RI and, if IR was set, DR
174 lwz r10,0(r23) ; Fetch the instruction
176 mtmsr r30 ; Trans and RI off
179 mtlr r28 ; Restore the LR
180 blr ; Return with instruction image in R10
188 lwz r6,savesrr1+4(r13) ; Get the srr1 value
189 lwz r4,SAVflags(r13) ; Pick up the flags
190 li r11,T_INSTRUCTION_ACCESS ; Set failing instruction fetch code
191 rlwimi r6,r1,0,1,4 ; Move the DSISR bits to the SRR1
192 oris r4,r4,hi16(SAVredrive) ; Set the redrive bit
193 stw r11,saveexception(r13) ; Set the replacement code
194 stw r4,SAVflags(r13) ; Set redrive request
195 stw r6,savesrr1+4(r13) ; Set the srr1 value
196 b EXT(EmulExit) ; Bail out to handle ISI...
200 ; This code emulates instructions that have failed because of operand
201 ; alignment. We decode the DSISR to figure out what we need to do.
204 ; 0001FC00 - Instruction designation
214 ; 000003E0 - Target/Source register
215 ; 0000001F - Register to update if update form
219 .globl EXT(AlignAssist)
222 bf-- pf64Bitb,aan64 ; Skip if not 64-bit
223 b EXT(AlignAssist64) ; Jump to the 64-bit code...
225 aan64: lwz r20,savedsisr(r13) ; Get the DSISR
226 li r0,0 ; Assume we emulate
227 mfsprg r31,0 ; Get the per_proc
228 mtcrf 0x10,r20 ; Put instruction ID in CR for later
229 lwz r21,spcFlags(r31) ; Grab the special flags
230 stw r0,savemisc3(r13) ; Assume that we emulate ok
231 mtcrf 0x08,r20 ; Put instruction ID in CR for later
232 rlwinm. r0,r21,0,runningVMbit,runningVMbit ; Are we running a VM?
233 mtcrf 0x04,r20 ; Put instruction ID in CR for later
234 lwz r22,savesrr1+4(r13) ; Get the SRR1
235 bne- aaPassAlong ; We are in a VM, no emulation for alignment exceptions...
236 lwz r19,dgFlags(0) ; Get the diagnostics flags
237 crxor iFloat,iOptype1,iOptype2 ; Set this to 0 if both bits are either 0 or 1
238 mr r26,r20 ; Save the DSISR
239 rlwinm. r0,r22,0,MSR_SE_BIT,MSR_SE_BIT ; Were we single stepping?
240 lwz r23,savedar+4(r13) ; Pick up the address that we want to access
241 crnot traceInst,cr0_eq ; Remember if trace is on
243 rlwinm. r0,r19,0,enaNotifyEMb,enaNotifyEMb ; Should we notify that an alignment exception happened?
244 mfmsr r30 ; Save the MSR for now
245 crnot iNotify,cr0_eq ; Remember to tell someone we did this
246 li r29,emfp0 ; Point to work area
247 crxor iFloat,iFloat,iOptype3 ; Set true if we have a floating point instruction
248 dcbz r29,r31 ; Clear and allocate a cache line for us to work in
249 rlwinm r24,r20,3,24,28 ; Get displacement to register to update if update form
250 rlwimi r20,r20,24,28,28 ; Move load/store indication to the bottom of index
251 rlwinm r22,r22,0,MSR_DR_BIT,MSR_DR_BIT ; Move rupt DR to DR for ifetch
252 rlwimi r20,r20,26,27,27 ; Move single/double indication to just above the bottom
253 rlwimi r22,r22,32-MSR_RI_BIT+MSR_DR_BIT,MSR_RI_BIT,MSR_RI_BIT ; Move DR to RI for i-fetch
254 lis r29,hi16(EXT(aaFPopTable)) ; High part of FP branch table
255 or r22,r30,r22 ; Set the DR and RI bits if translation was on
256 bf- iFloat,aaNotFloat ; This is not a floating point instruction...
257 ori r29,r29,lo16(EXT(aaFPopTable)) ; Low part of FP branch table
259 rlwimi r29,r20,0,22,28 ; Index into table based upon register||iDouble||iStore
260 mtctr r29 ; Get set to call the function
261 bt iStore,aaFPstore ; This is an FP store...
264 ; Here we handle floating point loads
267 aaFPload: crset cr0_eq ; Set this to see if we failed
268 mtmsr r22 ; Flip DR, RI
271 lwz r10,0(r23) ; Get the first word
272 bf- cr0_eq,aaLdNotDbl ; Jump out if we DSIed...
273 bf iDouble,aaLdNotDbl ; this is not a double...
274 lwz r11,4(r23) ; Get the second half
276 aaLdNotDbl: mr r4,r0 ; Save the DAR if we failed the access
278 mtmsr r30 ; Turn off translation again
281 bf- cr0_eq,aaRedriveAsDSI ; Go redrive this as a DSI...
283 stw r10,emfp0(r31) ; Save the first half
284 stw r11,emfp0+4(r31) ; Save the second half, just in case we need it
286 bctrl ; Go set the target FP register
288 b aaComExit ; All done, go exit...
291 ; Here we handle floating point stores
296 aaFPstore: bctrl ; Go save the source FP register
298 lwz r10,emfp0(r31) ; Get first word
299 crandc iDouble,iDouble,iOptype4 ; Change to 4-byte access if stfiwx
300 lwz r11,emfp0+4(r31) ; and the second
301 bf+ iOptype4,aaNotstfiwx ; This is not a stfiwx...
302 mr r10,r11 ; The stfiwx wants to store the second half
305 crset cr0_eq ; Set this to see if we failed
306 mtmsr r22 ; Flip DR, RI
309 stw r10,0(r23) ; Save the first word
310 bf- cr0_eq,aaStNotDbl ; Jump out if we DSIed...
311 bf iDouble,aaStNotDbl ; this is not a double...
312 stw r11,4(r23) ; Save the second half
314 aaStNotDbl: mr r4,r0 ; Save the DAR if we failed the access
318 bf- cr0_eq,aaRedriveAsDSI ; Go redrive this as a DSI...
321 ; Common exit routines
324 aaComExit: lwz r10,savesrr0+4(r13) ; Get the failing instruction address
325 add r24,r24,r13 ; Offset to update register
326 li r11,T_IN_VAIN ; Assume we are all done
327 addi r10,r10,4 ; Step to the next instruction
328 bf iUpdate,aaComExNU ; Skip if not an update form...
329 stw r23,saver0+4(r24) ; Update the target
331 aaComExNU: lwz r9,SAVflags(r13) ; Get the flags
332 stw r10,savesrr0+4(r13) ; Set new PC
333 bt- traceInst,aaComExitrd ; We are tracing, go emulate trace...
334 bf+ iNotify,aaComExGo ; Nothing special here, go...
336 li r11,T_ALIGNMENT ; Set the we just did an alignment exception....
338 aaComExGo: b EXT(EmulExit) ; We are done, no tracing on...
342 ; This is not a floating point operation
344 ; The table of these emulation routines is indexed by taking the low order 4 bits of
345 ; the instruction code in the DSISR and subtracting 7. If this comes up negative,
346 ; the instruction is not to be emulated. Then we add bit 0 of the code * 4. This
347 ; gives us a fairly compact and almost unique index. Both lwm and stmw map to 0 so
348 ; that one needs to be further reduced, and we end up with holes at a few indexes.
354 lis r19,hi16(aaEmTable) ; Point to high part of table address
355 rlwinm r3,r26,24,26,29 ; Isolate last 4 bits of op type * 4
356 rlwimi r19,r26,20,27,27 ; Get bit 0 of instruction code * 4 into bottom of table base
357 addic. r3,r3,-28 ; Subtract 7*4 to adjust index
358 ori r19,r19,lo16(aaEmTable) ; Low part of table address
359 blt- aaPassAlong ; We do not handle any of these (lwarx, stwcx., eciwx, ecowx)...
360 add r19,r19,r3 ; Point to emulation routine
361 rlwinm r18,r26,30,24,28 ; Get the target/source register displacement
363 mtctr r19 ; Set the routine address
365 bctr ; Go emulate the instruction...
368 ; This is the table of non-floating point emulation routines.
369 ; It is indexed by the code immediately above.
374 b aaLmwStmw ; This for lmw/stmw
375 b aaLswx ; This for lwwx
376 b aaLswi ; This for lswi
377 b aaStswx ; This for stswx
378 b aaStswi ; This for stswi
379 b aaLwbrx ; This for lwbrx
380 b aaPassAlong ; This an invalid index (6)
381 b aaStwbrx ; This for stwbrx
382 b aaPassAlong ; This an invalid index (8)
383 b aaLhbrx ; This for lhbrx
384 b aaPassAlong ; This an invalid index (A)
385 b aaSthbrx ; This for sthbrx
386 b aaDcbz ; This for dcbz
387 b aaPassAlong ; This an invalid index (D)
388 b aaPassAlong ; This an invalid index (E)
389 b aaPassAlong ; This an invalid index (F)
393 ; Here we handle the set up for the lmw and stmw. After that, we split off to the
394 ; individual routines.
396 ; Note also that after some set up, all of the string instructions come through here as well.
401 rlwinm r17,r18,31,1,29 ; Convert doublword based index to words
402 li r28,0 ; Set no extra bytes to move (used for string instructions)
403 subfic r17,r17,32*4 ; Calculate the length of the transfer
405 aaLSComm: addi r19,r13,saver0+4 ; Offset to registers in savearea
406 mr r16,r23 ; Make a hunk pointer
408 bt iUpdate,aaStmw ; This is the stmw...
414 aaLmwNxt: cmplwi cr1,r17,8*4 ; Is there enough to move 8?
415 blt- cr1,aaLmwNxtH ; Not enough for a full hunk...
416 subi r17,r17,8*4 ; Back off for another hunk
418 crset cr0_eq ; Set this to see if we failed
419 mtmsr r22 ; Flip DR, RI
422 lwz r2,0(r16) ; Load word 0
423 bf- cr0_eq,aaLmwB1 ; Error, bail...
424 lwz r15,4(r16) ; Load word 1
425 bf- cr0_eq,aaLmwB1 ; Error, bail...
426 lwz r14,8(r16) ; Load word 2
427 bf- cr0_eq,aaLmwB1 ; Error, bail...
428 lwz r5,12(r16) ; Load word 3
429 bf- cr0_eq,aaLmwB1 ; Error, bail...
430 lwz r6,16(r16) ; Load word 4
431 bf- cr0_eq,aaLmwB1 ; Error, bail...
432 lwz r7,20(r16) ; Load word 5
433 bf- cr0_eq,aaLmwB1 ; Error, bail...
434 lwz r8,24(r16) ; Load word 6
435 bf- cr0_eq,aaLmwB1 ; Error, bail...
436 lwz r9,28(r16) ; Load word 7
438 aaLmwB1: mr r4,r0 ; Remember DAR, jus in case we failed the access
439 mtmsr r30 ; Turn off DR, RI
442 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
444 addi r16,r16,8*4 ; Point up to next input aread
446 stwx r2,r19,r18 ; Store register
447 addi r18,r18,8 ; Next register
448 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
449 stwx r15,r19,r18 ; Store register
450 addi r18,r18,8 ; Next register
451 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
452 stwx r14,r19,r18 ; Store register
453 addi r18,r18,8 ; Next register
454 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
455 stwx r5,r19,r18 ; Store register
456 addi r18,r18,8 ; Next register
457 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
458 stwx r6,r19,r18 ; Store register
459 addi r18,r18,8 ; Next register
460 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
461 stwx r7,r19,r18 ; Store register
462 addi r18,r18,8 ; Next register
463 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
464 stwx r8,r19,r18 ; Store register
465 addi r18,r18,8 ; Next register
466 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
467 stwx r9,r19,r18 ; Store register
468 addi r18,r18,8 ; Next register
469 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
471 b aaLmwNxt ; Do the next hunk...
475 aaLmwNxtH: cmplwi cr1,r17,4*4 ; Do we have 4 left?
476 blt cr1,aaLmwL4 ; Nope...
478 subi r17,r17,4*4 ; Set count properly
480 crset cr0_eq ; Set this to see if we failed
481 mtmsr r22 ; Flip DR, RI, and maybe PR on
484 lwz r2,0(r16) ; Load word 0
485 bf- cr0_eq,aaLmwB2 ; Error, bail...
486 lwz r15,4(r16) ; Load word 1
487 bf- cr0_eq,aaLmwB2 ; Error, bail...
488 lwz r14,8(r16) ; Load word 2
489 bf- cr0_eq,aaLmwB2 ; Error, bail...
490 lwz r5,12(r16) ; Load word 3
492 aaLmwB2: mr r4,r0 ; Remember DAR, jus in case we failed the access
493 mtmsr r30 ; Turn off DR, RI
496 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
498 addi r16,r16,4*4 ; Point up to next input aread
500 stwx r2,r19,r18 ; Store register
501 addi r18,r18,8 ; Next register
502 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
503 stwx r15,r19,r18 ; Store register
504 addi r18,r18,8 ; Next register
505 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
506 stwx r14,r19,r18 ; Store register
507 addi r18,r18,8 ; Next register
508 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
509 stwx r5,r19,r18 ; Store register
510 addi r18,r18,8 ; Next register
511 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
513 aaLmwL4: or. r5,r17,r28 ; Do we have anything left?
514 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three full words left?
515 cmplwi cr2,r17,0 ; Do we have no full words left?
516 beq aaComExit ; Nothing left...
518 crset cr0_eq ; Set this to see if we failed
519 mtmsr r22 ; Flip DR, RI, and maybe PR on
522 beq- cr2,aaLmwBy ; No full words, get bytes...
524 lwz r2,0(r16) ; Pick up first word
525 bf- cr0_eq,aaLmwDn ; Read failed, escape...
526 addi r16,r16,4 ; Next input location
527 blt cr1,aaLmwBy ; We only had one, we are done...
529 lwz r15,0(r16) ; Pick up second word
530 bf- cr0_eq,aaLmwDn ; Read failed, escape...
531 addi r16,r16,4 ; Next input location
532 beq cr1,aaLmwBy ; We had two, we are done...
534 lwz r14,0(r16) ; Load word 3
535 addi r16,r16,4 ; Next input location
537 aaLmwBy: cmplwi cr2,r28,0 ; Any trailing bytes to do?
538 li r8,0 ; Clear second trailing byte
539 cmplwi cr1,r28,2 ; Check for 1, 2, or 3
540 li r9,0 ; Clear third trailing byte
541 beq+ cr2,aaLmwDn ; No trailing bytes...
543 lbz r5,0(r16) ; Pick up first trailing byte
544 bf- cr0_eq,aaLmwDn ; Read failed, escape...
545 blt cr1,aaLmwDn ; We only had one, we are done...
547 lbz r8,1(r16) ; Pick up second trailing byte
548 bf- cr0_eq,aaLmwDn ; Read failed, escape...
549 beq cr1,aaLmwDn ; We had two, we are done...
551 lbz r9,2(r16) ; Get last trailing byte
554 aaLmwDn: rlwinm r5,r5,24,0,7 ; Move first byte to top
555 cmplwi cr2,r17,0 ; Any full words to do?
556 mr r4,r0 ; Remember DAR, just in case we failed the access
557 rlwimi r9,r8,8,16,23 ; Move second byte above third byte
558 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three full words left?
559 mr r3,r30 ; Set the normal MSR
560 rlwimi r5,r9,8,8,23 ; Move bytes 1 and 2 after 0
562 mtmsr r30 ; Turn off DR, RI
565 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
567 beq- cr2,aaLmwCb ; No full words, copy bytes...
569 stwx r2,r19,r18 ; Store register
570 addi r18,r18,8 ; Next register
571 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
572 blt cr1,aaLmwCb ; We only had one, we are done...
574 stwx r15,r19,r18 ; Store register
575 addi r18,r18,8 ; Next register
576 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
577 beq cr1,aaLmwCb ; We had two, we are done...
579 stwx r14,r19,r18 ; Store register
580 addi r18,r18,8 ; Next register
581 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
583 aaLmwCb: mr. r28,r28 ; Any trailing bytes to do?
584 beq+ aaComExit ; Nope, leave...
586 stwx r5,r19,r18 ; Store register
588 b aaComExit ; We are done....
591 ; Store multiple word
597 crclr iUpdate ; Make sure we do not think this is an update form
599 aaStmwNxt: cmplwi cr1,r17,8*4 ; Is there enough to move 8?
600 blt- cr1,aaStmwNxtH ; Not enough for a full hunk...
601 subi r17,r17,8*4 ; Back off for another hunk
603 lwzx r2,r19,r18 ; Store register
604 addi r18,r18,8 ; Next register
605 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
606 lwzx r15,r19,r18 ; Store register
607 addi r18,r18,8 ; Next register
608 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
609 lwzx r14,r19,r18 ; Store register
610 addi r18,r18,8 ; Next register
611 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
612 lwzx r5,r19,r18 ; Store register
613 addi r18,r18,8 ; Next register
614 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
615 lwzx r6,r19,r18 ; Store register
616 addi r18,r18,8 ; Next register
617 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
618 lwzx r7,r19,r18 ; Store register
619 addi r18,r18,8 ; Next register
620 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
621 lwzx r8,r19,r18 ; Store register
622 addi r18,r18,8 ; Next register
623 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
624 lwzx r9,r19,r18 ; Store register
625 addi r18,r18,8 ; Next register
626 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
628 crset cr0_eq ; Set this to see if we failed
629 mtmsr r22 ; Flip DR, RI, and maybe PR on
632 stw r2,0(r16) ; Store word 0
633 bf- cr0_eq,aaStmwB1 ; Error, bail...
634 stw r15,4(r16) ; Store word 1
635 bf- cr0_eq,aaStmwB1 ; Error, bail...
636 stw r14,8(r16) ; Store word 2
637 bf- cr0_eq,aaStmwB1 ; Error, bail...
638 stw r5,12(r16) ; Store word 3
639 bf- cr0_eq,aaStmwB1 ; Error, bail...
640 stw r6,16(r16) ; Store word 4
641 bf- cr0_eq,aaStmwB1 ; Error, bail...
642 stw r7,20(r16) ; Store word 5
643 bf- cr0_eq,aaStmwB1 ; Error, bail...
644 stw r8,24(r16) ; Store word 6
645 bf- cr0_eq,aaStmwB1 ; Error, bail...
646 stw r9,28(r16) ; Store word 7
648 addi r16,r16,8*4 ; Point up to next output aread
651 aaStmwB1: mr r4,r0 ; Remember DAR, jus in case we failed the access
652 mtmsr r30 ; Normal MSR
655 bt- cr0_eq,aaStmwNxt ; We have more to do and no failed access...
656 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
660 aaStmwNxtH: cmplwi cr1,r17,(4*4) ; Do we have at least 4 left?
661 blt cr1,aaStmwL4 ; Nope...
662 subi r17,r17,4*4 ; Set count properly
664 lwzx r2,r19,r18 ; Store register
665 addi r18,r18,8 ; Next register
666 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
667 lwzx r15,r19,r18 ; Store register
668 addi r18,r18,8 ; Next register
669 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
670 lwzx r14,r19,r18 ; Store register
671 addi r18,r18,8 ; Next register
672 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
673 lwzx r5,r19,r18 ; Store register
674 addi r18,r18,8 ; Next register
675 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
677 crset cr0_eq ; Set this to see if we failed
678 mtmsr r22 ; Flip DR, RI
681 stw r2,0(r16) ; Store word 0
682 bf- cr0_eq,aaStmwB2 ; Error, bail...
683 stw r15,4(r16) ; Store word 1
684 bf- cr0_eq,aaStmwB2 ; Error, bail...
685 stw r14,8(r16) ; Store word 2
686 bf- cr0_eq,aaStmwB2 ; Error, bail...
687 stw r5,12(r16) ; Store word 3
689 addi r16,r16,4*4 ; Point up to next input aread
691 aaStmwB2: mr r4,r0 ; Remember DAR, jus in case we failed the access
692 mtmsr r30 ; Normal MSR
695 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
697 aaStmwL4: or. r5,r17,r28 ; Do we have anything left to do?
698 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three left?
699 cmplwi cr2,r17,0 ; Do we have no full words left?
700 beq aaComExit ; Nothing left...
702 beq- cr2,aaStmwBy1 ; No full words, check out bytes
704 lwzx r2,r19,r18 ; Store register
705 addi r18,r18,8 ; Next register
706 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
707 blt cr1,aaStmwBy1 ; We only had one, go save it...
709 lwzx r15,r19,r18 ; Store register
710 addi r18,r18,8 ; Next register
711 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
712 beq cr1,aaStmwBy1 ; We had two, go save it...
714 lwzx r14,r19,r18 ; Store register
715 addi r18,r18,8 ; Next register
716 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
718 aaStmwBy1: mr. r28,r28 ; Do we have any trailing bytes?
719 beq+ aaStmwSt ; Nope...
721 lwzx r5,r19,r18 ; Yes, pick up one extra register
723 aaStmwSt: crset cr0_eq ; Set this to see if we failed
724 mtmsr r22 ; Flip DR, RI
727 beq- cr2,aaStmwBy2 ; No words, check trailing bytes...
729 stw r2,0(r16) ; Save first word
730 bf- cr0_eq,aaStmwDn ; Store failed, escape...
731 addi r16,r16,4 ; Bump sink
732 blt cr1,aaStmwBy2 ; We only had one, we are done...
734 stw r15,0(r16) ; Save second word
735 bf- cr0_eq,aaStmwDn ; Store failed, escape...
736 addi r16,r16,4 ; Bump sink
737 beq cr1,aaStmwBy2 ; We had two, we are done...
739 stw r14,0(r16) ; Save third word
740 bf- cr0_eq,aaStmwDn ; Store failed, escape...
741 addi r16,r16,4 ; Bump sink
743 aaStmwBy2: rlwinm r2,r5,8,24,31 ; Get byte 0
744 cmplwi cr2,r28,0 ; Any trailing bytes to do?
745 rlwinm r14,r5,24,24,31 ; Get byte 3
746 li r8,0 ; Clear second trailing byte
747 cmplwi cr1,r28,2 ; Check for 1, 2, or 3
748 li r9,0 ; Clear third trailing byte
749 beq+ cr2,aaStmwDn ; No trailing bytes...
750 rlwinm r15,r5,16,24,31 ; Get byte 1
752 stb r2,0(r16) ; Save first byte
753 bf- cr0_eq,aaStmwDn ; Read failed, escape...
754 blt cr1,aaStmwDn ; We only had one, we are done...
756 stb r15,1(r16) ; Save second byte
757 bf- cr0_eq,aaStmwDn ; Read failed, escape...
758 beq cr1,aaStmwDn ; We had two, we are done...
760 stb r14,2(r16) ; Save third byte
762 aaStmwDn: mr r4,r0 ; Remember DAR, jus in case we failed the access
763 mtmsr r30 ; Normal MSR
766 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
768 b aaComExit ; We are done....
772 ; Load String Indexed
777 aaLswx: lwz r17,savexer+4(r13) ; Pick up the XER
778 crclr iUpdate ; Make sure we think this the load form
779 rlwinm. r25,r17,0,25,31 ; Get the number of bytes to load
780 rlwinm r28,r17,0,30,31 ; Get the number of bytes past an even word
781 beq- aaComExit ; Do nothing if 0 length...
782 xor r17,r25,r28 ; Round down to an even word boundary
783 b aaLSComm ; Join up with common load/store code...
787 ; Load String Immediate
792 aaLswi: mr r9,r23 ; Save the DAR
793 bl eIFetch ; Get the instruction image
794 bne- eRedriveAsISI ; Go redrive this as an ISI...
795 rlwinm r25,r10,21,27,31 ; Get the number of bytes to load
796 crclr iUpdate ; Make sure we think this the load form
797 subi r25,r25,1 ; Back off by 1
798 rlwinm r25,r25,0,27,31 ; Clear back down
799 addi r25,r25,1 ; Add back the 1 to convert 0 to 32
800 rlwinm r28,r25,0,30,31 ; Get the number of bytes past an even word
801 xor r17,r25,r28 ; Round down to an even word boundary
802 mr r23,r9 ; Move back the DAR
803 b aaLSComm ; Join up with common load/store code...
806 ; Store String Indexed
811 aaStswx: lwz r17,savexer+4(r13) ; Pick up the XER
812 crclr iUpdate ; Make sure this is clear in case we have 0 length
813 rlwinm. r25,r17,0,25,31 ; Get the number of bytes to load
814 rlwinm r28,r17,0,30,31 ; Get the number of bytes past an even word
815 beq- aaComExit ; Do nothing if 0 length...
816 xor r17,r25,r28 ; Round down to an even word boundary
817 crset iUpdate ; Make sure we think this the store form
818 b aaLSComm ; Join up with common load/store code...
822 ; Store String Immediate
827 aaStswi: mr r9,r23 ; Save the DAR
828 bl eIFetch ; Get the instruction image
829 bne- eRedriveAsISI ; Go redrive this as an ISI...
830 rlwinm r25,r10,21,27,31 ; Get the number of bytes to load
831 crclr iUpdate ; Make sure we think this the load form
832 subi r25,r25,1 ; Back off by 1
833 rlwinm r25,r25,0,27,31 ; Clear back down
834 addi r25,r25,1 ; Add back the 1 to convert 0 to 32
835 rlwinm r28,r25,21,30,31 ; Get the number of bytes past an even word
836 xor r17,r25,r28 ; Round down to an even word boundary
837 mr r23,r9 ; Move back the DAR
838 b aaLSComm ; Join up with common load/store code...
842 ; Load byte-reversed word
848 add r18,r18,r13 ; Index to source register
850 crset cr0_eq ; Set this to see if we failed
851 mtmsr r22 ; Flip DR, RI, and maybe PR on
854 lwz r11,0(r23) ; Load the word
856 mr r4,r0 ; Save the DAR if we failed the access
857 mtmsr r30 ; Restore normal MSR
860 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
862 rlwinm r10,r11,8,0,31 ; Get byte 0 to 3 and byte 2 to 1
863 rlwimi r10,r11,24,16,23 ; Move byte 1 to byte 2
864 rlwimi r10,r11,24,0,7 ; Move byte 3 to byte 0
866 stw r10,saver0+4(r18) ; Set the register
868 b aaComExit ; All done, go exit...
873 ; Store byte-reversed word
879 add r18,r18,r13 ; Index to source register
880 lwz r11,saver0+4(r18) ; Get the register to store
882 rlwinm r10,r11,8,0,31 ; Get byte 0 to 3 and byte 2 to 1
883 rlwimi r10,r11,24,16,23 ; Move byte 1 to byte 2
884 rlwimi r10,r11,24,0,7 ; Move byte 3 to byte 0
886 crset cr0_eq ; Set this to see if we failed
887 mtmsr r22 ; Flip DR, RI, and maybe PR on
890 stw r10,0(r23) ; Store the reversed halfword
892 mr r4,r0 ; Save the DAR if we failed the access
893 mtmsr r30 ; Restore normal MSR
896 bt+ cr0_eq,aaComExit ; All done, go exit...
897 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
902 ; Load byte-reversed halfword
908 add r18,r18,r13 ; Index to source register
910 crset cr0_eq ; Set this to see if we failed
911 mtmsr r22 ; Flip DR, RI, and maybe PR on
914 lhz r11,0(r23) ; Load the halfword
916 mr r4,r0 ; Save the DAR if we failed the access
917 mtmsr r30 ; Restore normal MSR
920 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
922 rlwinm r10,r11,8,16,23 ; Rotate bottom byte up one and clear everything else
923 rlwimi r10,r11,24,24,31 ; Put old second from bottom into bottom
925 stw r10,saver0+4(r18) ; Set the register
927 b aaComExit ; All done, go exit...
931 ; Store byte-reversed halfword
937 add r18,r18,r13 ; Index to source register
938 lwz r10,saver0+4(r18) ; Get the register to store
939 rlwinm r10,r10,8,0,31 ; Rotate bottom byte up one
940 rlwimi r10,r10,16,24,31 ; Put old second from bottom into bottom
942 crset cr0_eq ; Set this to see if we failed
943 mtmsr r22 ; Flip DR, RI, and maybe PR on
946 sth r10,0(r23) ; Store the reversed halfword
948 mr r4,r0 ; Save the DAR if we failed the access
949 mtmsr r30 ; Restore normal MSR
952 bt+ cr0_eq,aaComExit ; All done, go exit...
953 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
956 ; Data cache block zero
962 lwz r0,savesrr0+4(r13) ; get instruction address
963 li r4,_COMM_PAGE_BASE_ADDRESS
964 rlwinm r23,r23,0,0,26 ; Round EA back to a 32-byte boundary
965 sub r4,r0,r4 ; compute instruction offset from base of commpage
966 cmplwi r4,_COMM_PAGE_AREA_USED ; did fault occur in commpage?
967 bge+ aaDcbz1 ; skip if not in commpage
968 lwz r4,savecr(r13) ; if we take a dcbz in the commpage...
969 rlwinm r4,r4,0,0,27 ; ...clear users cr7 as a flag for commpage code
972 crset cr0_eq ; Set this to see if we failed
973 li r0,0 ; Clear this out
974 mtmsr r22 ; Flip DR, RI, and maybe PR on
977 stw r0,0(r23) ; Clear word
978 bne- aaDcbzXit ; Got DSI, we are stopping...
979 stw r0,4(r23) ; Clear word
980 bne- aaDcbzXit ; Got DSI, we are stopping...
981 stw r0,8(r23) ; Clear word
982 bne- aaDcbzXit ; Got DSI, we are stopping...
983 stw r0,12(r23) ; Clear word
984 bne- aaDcbzXit ; Got DSI, we are stopping...
985 stw r0,16(r23) ; Clear word
986 bne- aaDcbzXit ; Got DSI, we are stopping...
987 stw r0,20(r23) ; Clear word
988 bne- aaDcbzXit ; Got DSI, we are stopping...
989 stw r0,24(r23) ; Clear word
990 bne- aaDcbzXit ; Got DSI, we are stopping...
991 stw r0,28(r23) ; Clear word
993 aaDcbzXit: mr r4,r0 ; Save the DAR if we failed the access
994 mtmsr r30 ; Restore normal MSR
997 crclr iUpdate ; Make sure we do not think this is an update form
999 bt+ cr0_eq,aaComExit ; All done, go exit...
1000 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
1004 ; Unhandled alignment exception, pass it along
1008 li r0,1 ; Indicate that we failed to emulate
1009 stw r0,savemisc3(r13) ; Assume that we emulate ok
1016 ; We go here to emulate a trace exception after we have handled alignment error
1022 lis r11,hi16(srr1clr) ; Get the bits we need to clear
1023 oris r9,r9,hi16(SAVredrive) ; Set the redrive bit
1024 andc r12,r12,r11 ; Clear what needs to be cleared
1025 li r11,T_TRACE ; Set trace interrupt
1026 stw r9,SAVflags(r13) ; Set the flags
1027 stw r11,saveexception(r13) ; Set the exception code
1028 b EXT(EmulExit) ; Exit and do trace interrupt...
1036 mr r20,r1 ; Save the DSISR
1038 lwz r4,SAVflags(r13) ; Pick up the flags
1039 li r11,T_DATA_ACCESS ; Set failing data access code
1040 oris r4,r4,hi16(SAVredrive) ; Set the redrive bit
1041 stw r20,savedsisr(r13) ; Set the DSISR of failed access
1042 stw r21,savedar+4(r13) ; Set the address of the failed access
1043 stw r11,saveexception(r13) ; Set the replacement code
1044 stw r4,SAVflags(r13) ; Set redrive request
1045 b EXT(EmulExit) ; Bail out to handle ISI...
1050 ; Table of functions to load or store floating point registers
1051 ; This table is indexed reg||size||dir. That means that each
1052 ; like load/store pair (e.g., lfd f31/stfd f31) are within the same
1053 ; quadword, which is the current ifetch size. We expect most of the
1054 ; unaligned accesses to be part of copies, therefore, with this
1055 ; organization, we will save the ifetch of the store after the load.
1058 .align 10 ; Make sure we are on a 1k boundary
1059 .globl EXT(aaFPopTable)
1062 lfs f0,emfp0(r31) ; Load single variant
1065 stfs f0,emfp0(r31) ; Store single variant
1068 lfd f0,emfp0(r31) ; Load double variant
1071 stfd f0,emfp0(r31) ; Store double variant
1074 lfs f1,emfp0(r31) ; Load single variant
1077 stfs f1,emfp0(r31) ; Store single variant
1080 lfd f1,emfp0(r31) ; Load double variant
1083 stfd f1,emfp0(r31) ; Store double variant
1086 lfs f2,emfp0(r31) ; Load single variant
1089 stfs f2,emfp0(r31) ; Store single variant
1092 lfd f2,emfp0(r31) ; Load double variant
1095 stfd f2,emfp0(r31) ; Store double variant
1098 lfs f3,emfp0(r31) ; Load single variant
1101 stfs f3,emfp0(r31) ; Store single variant
1104 lfd f3,emfp0(r31) ; Load double variant
1107 stfd f3,emfp0(r31) ; Store double variant
1110 lfs f4,emfp0(r31) ; Load single variant
1113 stfs f4,emfp0(r31) ; Store single variant
1116 lfd f4,emfp0(r31) ; Load double variant
1119 stfd f4,emfp0(r31) ; Store double variant
1122 lfs f5,emfp0(r31) ; Load single variant
1125 stfs f5,emfp0(r31) ; Store single variant
1128 lfd f5,emfp0(r31) ; Load double variant
1131 stfd f5,emfp0(r31) ; Store double variant
1134 lfs f6,emfp0(r31) ; Load single variant
1137 stfs f6,emfp0(r31) ; Store single variant
1140 lfd f6,emfp0(r31) ; Load double variant
1143 stfd f6,emfp0(r31) ; Store double variant
1146 lfs f7,emfp0(r31) ; Load single variant
1149 stfs f7,emfp0(r31) ; Store single variant
1152 lfd f7,emfp0(r31) ; Load double variant
1155 stfd f7,emfp0(r31) ; Store double variant
1158 lfs f8,emfp0(r31) ; Load single variant
1161 stfs f8,emfp0(r31) ; Store single variant
1164 lfd f8,emfp0(r31) ; Load double variant
1167 stfd f8,emfp0(r31) ; Store double variant
1170 lfs f9,emfp0(r31) ; Load single variant
1173 stfs f9,emfp0(r31) ; Store single variant
1176 lfd f9,emfp0(r31) ; Load double variant
1179 stfd f9,emfp0(r31) ; Store double variant
1182 lfs f10,emfp0(r31) ; Load single variant
1185 stfs f10,emfp0(r31) ; Store single variant
1188 lfd f10,emfp0(r31) ; Load double variant
1191 stfd f10,emfp0(r31) ; Store double variant
1194 lfs f11,emfp0(r31) ; Load single variant
1197 stfs f11,emfp0(r31) ; Store single variant
1200 lfd f11,emfp0(r31) ; Load double variant
1203 stfd f11,emfp0(r31) ; Store double variant
1206 lfs f12,emfp0(r31) ; Load single variant
1209 stfs f12,emfp0(r31) ; Store single variant
1212 lfd f12,emfp0(r31) ; Load double variant
1215 stfd f12,emfp0(r31) ; Store double variant
1218 lfs f13,emfp0(r31) ; Load single variant
1221 stfs f13,emfp0(r31) ; Store single variant
1224 lfd f13,emfp0(r31) ; Load double variant
1227 stfd f13,emfp0(r31) ; Store double variant
1230 lfs f14,emfp0(r31) ; Load single variant
1233 stfs f14,emfp0(r31) ; Store single variant
1236 lfd f14,emfp0(r31) ; Load double variant
1239 stfd f14,emfp0(r31) ; Store double variant
1242 lfs f15,emfp0(r31) ; Load single variant
1245 stfs f15,emfp0(r31) ; Store single variant
1248 lfd f15,emfp0(r31) ; Load double variant
1251 stfd f15,emfp0(r31) ; Store double variant
1254 lfs f16,emfp0(r31) ; Load single variant
1257 stfs f16,emfp0(r31) ; Store single variant
1260 lfd f16,emfp0(r31) ; Load double variant
1263 stfd f16,emfp0(r31) ; Store double variant
1266 lfs f17,emfp0(r31) ; Load single variant
1269 stfs f17,emfp0(r31) ; Store single variant
1272 lfd f17,emfp0(r31) ; Load double variant
1275 stfd f17,emfp0(r31) ; Store double variant
1278 lfs f18,emfp0(r31) ; Load single variant
1281 stfs f18,emfp0(r31) ; Store single variant
1284 lfd f18,emfp0(r31) ; Load double variant
1287 stfd f18,emfp0(r31) ; Store double variant
1290 lfs f19,emfp0(r31) ; Load single variant
1293 stfs f19,emfp0(r31) ; Store single variant
1296 lfd f19,emfp0(r31) ; Load double variant
1299 stfd f19,emfp0(r31) ; Store double variant
1302 lfs f20,emfp0(r31) ; Load single variant
1305 stfs f20,emfp0(r31) ; Store single variant
1308 lfd f20,emfp0(r31) ; Load double variant
1311 stfd f20,emfp0(r31) ; Store double variant
1314 lfs f21,emfp0(r31) ; Load single variant
1317 stfs f21,emfp0(r31) ; Store single variant
1320 lfd f21,emfp0(r31) ; Load double variant
1323 stfd f21,emfp0(r31) ; Store double variant
1326 lfs f22,emfp0(r31) ; Load single variant
1329 stfs f22,emfp0(r31) ; Store single variant
1332 lfd f22,emfp0(r31) ; Load double variant
1335 stfd f22,emfp0(r31) ; Store double variant
1338 lfs f23,emfp0(r31) ; Load single variant
1341 stfs f23,emfp0(r31) ; Store single variant
1344 lfd f23,emfp0(r31) ; Load double variant
1347 stfd f23,emfp0(r31) ; Store double variant
1350 lfs f24,emfp0(r31) ; Load single variant
1353 stfs f24,emfp0(r31) ; Store single variant
1356 lfd f24,emfp0(r31) ; Load double variant
1359 stfd f24,emfp0(r31) ; Store double variant
1362 lfs f25,emfp0(r31) ; Load single variant
1365 stfs f25,emfp0(r31) ; Store single variant
1368 lfd f25,emfp0(r31) ; Load double variant
1371 stfd f25,emfp0(r31) ; Store double variant
1374 lfs f26,emfp0(r31) ; Load single variant
1377 stfs f26,emfp0(r31) ; Store single variant
1380 lfd f26,emfp0(r31) ; Load double variant
1383 stfd f26,emfp0(r31) ; Store double variant
1386 lfs f27,emfp0(r31) ; Load single variant
1389 stfs f27,emfp0(r31) ; Store single variant
1392 lfd f27,emfp0(r31) ; Load double variant
1395 stfd f27,emfp0(r31) ; Store double variant
1398 lfs f28,emfp0(r31) ; Load single variant
1401 stfs f28,emfp0(r31) ; Store single variant
1404 lfd f28,emfp0(r31) ; Load double variant
1407 stfd f28,emfp0(r31) ; Store double variant
1410 lfs f29,emfp0(r31) ; Load single variant
1413 stfs f29,emfp0(r31) ; Store single variant
1416 lfd f29,emfp0(r31) ; Load double variant
1419 stfd f29,emfp0(r31) ; Store double variant
1422 lfs f30,emfp0(r31) ; Load single variant
1425 stfs f30,emfp0(r31) ; Store single variant
1428 lfd f30,emfp0(r31) ; Load double variant
1431 stfd f30,emfp0(r31) ; Store double variant
1434 lfs f31,emfp0(r31) ; Load single variant
1437 stfs f31,emfp0(r31) ; Store single variant
1440 lfd f31,emfp0(r31) ; Load double variant
1443 stfd f31,emfp0(r31) ; Store double variant