]> git.saurik.com Git - apple/xnu.git/blame_incremental - osfmk/ppc/Emulate.s
xnu-792.12.6.tar.gz
[apple/xnu.git] / osfmk / ppc / Emulate.s
... / ...
CommitLineData
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
5 *
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
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
14 * agreement.
15 *
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
18 * file.
19 *
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
27 *
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
29 */
30/*
31 Emulate.s
32
33 Emulate instructions and traps.
34
35 Lovingly crafted by Bill Angell using traditional methods and only natural or recycled materials.
36 No animal products are used other than rendered otter bile and deep fried pork lard.
37
38*/
39
40#include <ppc/asm.h>
41#include <ppc/proc_reg.h>
42#include <ppc/exception.h>
43#include <ppc/cpu_capabilities.h>
44#include <mach/machine/vm_param.h>
45#include <assym.s>
46
47#define traceInst 30
48#define dssAllDone 29
49
50; General stuff what happens here:
51; 1) All general context saved, interrupts off, translation off
52; 2) Vector and floating point disabled, but there may be live context.
53; This code is responsible for saving and restoring what is used. This
54; includes exception states, java mode, etc.
55; 3) No attempt is made to resolve page faults. PTE misses are handled
56; automatically, but actual faults (ala copyin/copyout) are not. If
57; a fault does occur, the exception that caused entry to the emulation
58; routine is remapped to either an instruction or data miss (depending
59; upon the stage detected) and redrived through the exception handler.
60; The only time that an instruction fault can happen is when a different
61; processor removes a mapping between our original fault and when we
62; fetch the assisted instruction. For an assisted instruction, data
63; faults should not occur (except in the MP case). For a purely
64; emulated instruction, faults can occur.
65;
66;
67
68
69 .align 5
70 .globl EXT(Emulate)
71
72LEXT(Emulate)
73
74 bf-- pf64Bitb,emn64 ; Skip if not 64-bit
75 b EXT(Emulate64) ; Jump to the 64-bit code...
76
77emn64: mfsprg r31,0 ; Get the per_proc
78 lwz r12,savesrr1+4(r13) ; Get the exception info
79 rlwinm. r0,r12,0,SRR1_PRG_ILL_INS_BIT,SRR1_PRG_ILL_INS_BIT ; Emulation candidate?
80 lwz r30,dgFlags(0) ; Get the flags
81 beq+ eExit ; Nope, do not try to emulate...
82
83 rlwinm. r0,r30,0,enaDiagEMb,enaDiagEMb ; Do we want to try to emulate something?
84 mfsprg r28,2 ; Get the processor features
85 beq+ eExit ; No emulation allowed...
86
87 rlwinm. r28,r28,0,pfAltivecb,pfAltivecb ; Do we have Altivec on this machine?
88 beq eNoVect ; Nope, no Altivec...
89
90 dssall ; We need to kill streams because we are going to flip to problem state
91 sync
92
93eNoVect: bl eIFetch ; Get the instruction image
94 bne- eRedriveAsISI ; Go redrive this as an ISI...
95
96 rlwinm. r0,r10,0,0,5 ; See if we have the "special" op code here
97 rlwinm r20,r10,16,22,31 ; Set rS/rD and rA
98 bne+ eExit ; Not special op, ignore...
99
100 rlwinm r0,r10,31,22,31 ; Extract the sub op code
101 crclr cr1_eq ; Clear
102 rlwimi r20,r10,14,15,16 ; Move bits 29 and 30 of instruction to 15 and 16 of DSISR
103 cmplwi r0,790 ; lhbrx?
104 rlwimi r20,r10,8,17,17 ; Move bit 25 to bit 17
105 cror cr1_eq,cr1_eq,cr0_eq ; Remember
106 cmplwi r0,534 ; lwbrx?
107 rlwimi r20,r10,3,18,21 ; Move bit 21-24 to bit 18-21
108 cror cr1_eq,cr1_eq,cr0_eq ; Remember
109 cmplwi r0,918 ; sthbrx?
110 cror cr1_eq,cr1_eq,cr0_eq ; Remember
111 cmplwi r0,662 ; stwbrx?
112 cror cr1_eq,cr1_eq,cr0_eq ; Remember
113 cmplwi r0,1014 ; dcbz?
114 cror cr1_eq,cr1_eq,cr0_eq ; Remember
115 cmplwi r0,533 ; lswx?
116 cror cr1_eq,cr1_eq,cr0_eq ; Remember
117 cmplwi r0,661 ; stswx?
118 cror cr1_eq,cr1_eq,cr0_eq ; Remember
119 bne cr1_eq,eNotIndex ; Go check non-index forms...
120
121 rlwinm. r21,r10,19,24,28 ; Extract index to rA to build EA
122 rlwinm r22,r10,24,24,28 ; Extract index to rB
123 addi r24,r13,saver0+4 ; Point to the start of registers
124 li r19,0 ; Assume 0 base
125 beq eZeroBase ; Yes...
126 lwzx r19,r24,r21 ; Get the base register value
127
128eZeroBase: lwzx r22,r24,r22 ; Get the index value
129 add r22,r22,r19 ; Get DAR
130 b eFinishUp ; Done, go finish up...
131
132eNotIndex: cmplwi r0,725 ; stswi?
133 cror cr1_eq,cr1_eq,cr0_eq ; Remember
134 cmplwi r0,597 ; lswi?
135 cror cr1_eq,cr1_eq,cr0_eq ; Remember
136 bne cr1,eExit ; Not one we handle...
137
138 rlwinm. r21,r10,19,24,28 ; Extract index to rA to build EA
139 addi r24,r13,saver0+4 ; Point to the start of registers
140 li r22,0 ; Assume 0 base
141 beq eFinishUp ; Yes, it is...
142 lwzx r22,r24,r21 ; Get the base register value
143
144eFinishUp: stw r20,savedsisr(r13) ; Set the DSISR
145 li r11,T_ALIGNMENT ; Get the exception code
146 stw r22,savedar+4(r13) ; Save the DAR
147 stw r11,saveexception(r13) ; Set the exception code
148 b EXT(AlignAssist) ; Go emulate the handler...
149
150
151eExit: b EXT(EmulExit) ; Just return for now...
152
153
154;
155; Fetch the failing instruction.
156; Image returned in R10 if CR0_EQ is false, otherwise, an ISI should be generated/
157; The cr bit kernAccess is set if this was a kernel access.
158; R1 has the DSISR if access failed.
159;
160
161 .align 5
162
163eIFetch: lwz r23,savesrr1+4(r13) ; Get old MSR
164 mflr r28 ; Save return
165
166 rlwinm. r22,r23,0,MSR_PR_BIT,MSR_PR_BIT ; Within kernel?
167
168 mfmsr r30 ; Save the MSR for now
169 lwz r23,savesrr0+4(r13) ; Get instruction address
170
171 ori r22,r30,lo16(MASK(MSR_DR)|MASK(MSR_RI)) ; Set RI and DR onto access MSR
172
173 crset cr0_eq ; Set this to see if we failed
174 mtmsr r22 ; Flip DR, RI, and maybe PR on
175 isync
176
177 lwz r10,0(r23) ; Fetch the instruction
178
179 mtmsr r30 ; Trans and RI off
180 isync
181
182 mtlr r28 ; Restore the LR
183 blr ; Return with instruction image in R10
184
185
186;
187; Redrive as an ISI
188;
189
190eRedriveAsISI:
191 lwz r6,savesrr1+4(r13) ; Get the srr1 value
192 lwz r4,SAVflags(r13) ; Pick up the flags
193 li r11,T_INSTRUCTION_ACCESS ; Set failing instruction fetch code
194 rlwimi r6,r1,0,0,4 ; Move the DSISR bits to the SRR1
195 oris r4,r4,hi16(SAVredrive) ; Set the redrive bit
196 stw r11,saveexception(r13) ; Set the replacement code
197 stw r4,SAVflags(r13) ; Set redrive request
198 stw r6,savesrr1+4(r13) ; Set the srr1 value
199 b EXT(EmulExit) ; Bail out to handle ISI...
200
201
202;
203; This code emulates instructions that have failed because of operand
204; alignment. We decode the DSISR to figure out what we need to do.
205;
206; DSISR:
207; 0001FC00 - Instruction designation
208#define iFloat 12
209#define iOptype1 15
210#define iOptype2 16
211#define iOptype3 18
212#define iOptype4 19
213#define iUpdate 17
214#define iStore 20
215#define iDouble 21
216#define iNotify 22
217; 000003E0 - Target/Source register
218; 0000001F - Register to update if update form
219;
220
221 .align 5
222 .globl EXT(AlignAssist)
223
224LEXT(AlignAssist)
225 bf-- pf64Bitb,aan64 ; Skip if not 64-bit
226 b EXT(AlignAssist64) ; Jump to the 64-bit code...
227
228aan64: lwz r20,savedsisr(r13) ; Get the DSISR
229 li r0,0 ; Assume we emulate
230 mfsprg r31,0 ; Get the per_proc
231 mtcrf 0x10,r20 ; Put instruction ID in CR for later
232 lwz r21,spcFlags(r31) ; Grab the special flags
233 stw r0,savemisc3(r13) ; Assume that we emulate ok
234 mtcrf 0x08,r20 ; Put instruction ID in CR for later
235 rlwinm. r0,r21,0,runningVMbit,runningVMbit ; Are we running a VM?
236 mtcrf 0x04,r20 ; Put instruction ID in CR for later
237 lwz r22,savesrr1+4(r13) ; Get the SRR1
238 bne- aaPassAlong ; We are in a VM, no emulation for alignment exceptions...
239 lwz r19,dgFlags(0) ; Get the diagnostics flags
240 crxor iFloat,iOptype1,iOptype2 ; Set this to 0 if both bits are either 0 or 1
241 mr r26,r20 ; Save the DSISR
242 rlwinm. r0,r22,0,MSR_SE_BIT,MSR_SE_BIT ; Were we single stepping?
243 lwz r23,savedar+4(r13) ; Pick up the address that we want to access
244 crnot traceInst,cr0_eq ; Remember if trace is on
245
246 rlwinm. r0,r19,0,enaNotifyEMb,enaNotifyEMb ; Should we notify that an alignment exception happened?
247 mfmsr r30 ; Save the MSR for now
248 crnot iNotify,cr0_eq ; Remember to tell someone we did this
249 li r29,emfp0 ; Point to work area
250 crxor iFloat,iFloat,iOptype3 ; Set true if we have a floating point instruction
251 dcbz r29,r31 ; Clear and allocate a cache line for us to work in
252 rlwinm r24,r20,3,24,28 ; Get displacement to register to update if update form
253 rlwimi r20,r20,24,28,28 ; Move load/store indication to the bottom of index
254 ori r22,r30,lo16(MASK(MSR_DR)|MASK(MSR_RI)) ; Set RI onto access MSR
255 rlwimi r20,r20,26,27,27 ; Move single/double indication to just above the bottom
256 lis r29,hi16(EXT(aaFPopTable)) ; High part of FP branch table
257 bf- iFloat,aaNotFloat ; This is not a floating point instruction...
258 ori r29,r29,lo16(EXT(aaFPopTable)) ; Low part of FP branch table
259
260 rlwimi r29,r20,0,22,28 ; Index into table based upon register||iDouble||iStore
261 mtctr r29 ; Get set to call the function
262 bt iStore,aaFPstore ; This is an FP store...
263
264;
265; Here we handle floating point loads
266;
267
268aaFPload: crset cr0_eq ; Set this to see if we failed
269 mtmsr r22 ; Flip DR, RI
270 isync
271
272 lwz r10,0(r23) ; Get the first word
273 bf- cr0_eq,aaLdNotDbl ; Jump out if we DSIed...
274 bf iDouble,aaLdNotDbl ; this is not a double...
275 lwz r11,4(r23) ; Get the second half
276
277aaLdNotDbl: mr r4,r0 ; Save the DAR if we failed the access
278
279 mtmsr r30 ; Turn off translation again
280 isync
281
282 bf- cr0_eq,aaRedriveAsDSI ; Go redrive this as a DSI...
283
284 stw r10,emfp0(r31) ; Save the first half
285 stw r11,emfp0+4(r31) ; Save the second half, just in case we need it
286
287 bctrl ; Go set the target FP register
288
289 b aaComExit ; All done, go exit...
290
291;
292; Here we handle floating point stores
293;
294
295 .align 5
296
297aaFPstore: bctrl ; Go save the source FP register
298
299 lwz r10,emfp0(r31) ; Get first word
300 crandc iDouble,iDouble,iOptype4 ; Change to 4-byte access if stfiwx
301 lwz r11,emfp0+4(r31) ; and the second
302 bf+ iOptype4,aaNotstfiwx ; This is not a stfiwx...
303 mr r10,r11 ; The stfiwx wants to store the second half
304
305aaNotstfiwx:
306 crset cr0_eq ; Set this to see if we failed
307 mtmsr r22 ; Flip DR, RI
308 isync
309
310 stw r10,0(r23) ; Save the first word
311 bf- cr0_eq,aaStNotDbl ; Jump out if we DSIed...
312 bf iDouble,aaStNotDbl ; this is not a double...
313 stw r11,4(r23) ; Save the second half
314
315aaStNotDbl: mr r4,r0 ; Save the DAR if we failed the access
316 mtmsr r30 ; Turn off
317 isync
318
319 bf- cr0_eq,aaRedriveAsDSI ; Go redrive this as a DSI...
320
321;
322; Common exit routines
323;
324
325aaComExit: lwz r10,savesrr0+4(r13) ; Get the failing instruction address
326 add r24,r24,r13 ; Offset to update register
327 li r11,T_IN_VAIN ; Assume we are all done
328 addi r10,r10,4 ; Step to the next instruction
329 bf iUpdate,aaComExNU ; Skip if not an update form...
330 stw r23,saver0+4(r24) ; Update the target
331
332aaComExNU: lwz r9,SAVflags(r13) ; Get the flags
333 stw r10,savesrr0+4(r13) ; Set new PC
334 bt- traceInst,aaComExitrd ; We are tracing, go emulate trace...
335 bf+ iNotify,aaComExGo ; Nothing special here, go...
336
337 li r11,T_ALIGNMENT ; Set the we just did an alignment exception....
338
339aaComExGo: b EXT(EmulExit) ; We are done, no tracing on...
340
341
342;
343; This is not a floating point operation
344;
345; The table of these emulation routines is indexed by taking the low order 4 bits of
346; the instruction code in the DSISR and subtracting 7. If this comes up negative,
347; the instruction is not to be emulated. Then we add bit 0 of the code * 4. This
348; gives us a fairly compact and almost unique index. Both lwm and stmw map to 0 so
349; that one needs to be further reduced, and we end up with holes at a few indexes.
350;
351
352 .align 5
353
354aaNotFloat:
355 lis r19,hi16(aaEmTable) ; Point to high part of table address
356 rlwinm r3,r26,24,26,29 ; Isolate last 4 bits of op type * 4
357 rlwimi r19,r26,20,27,27 ; Get bit 0 of instruction code * 4 into bottom of table base
358 addic. r3,r3,-28 ; Subtract 7*4 to adjust index
359 ori r19,r19,lo16(aaEmTable) ; Low part of table address
360 blt- aaPassAlong ; We do not handle any of these (lwarx, stwcx., eciwx, ecowx)...
361 add r19,r19,r3 ; Point to emulation routine
362 rlwinm r18,r26,30,24,28 ; Get the target/source register displacement
363
364 mtctr r19 ; Set the routine address
365
366 bctr ; Go emulate the instruction...
367
368;
369; This is the table of non-floating point emulation routines.
370; It is indexed by the code immediately above.
371
372 .align 5
373
374aaEmTable:
375 b aaLmwStmw ; This for lmw/stmw
376 b aaLswx ; This for lwwx
377 b aaLswi ; This for lswi
378 b aaStswx ; This for stswx
379 b aaStswi ; This for stswi
380 b aaLwbrx ; This for lwbrx
381 b aaPassAlong ; This an invalid index (6)
382 b aaStwbrx ; This for stwbrx
383 b aaPassAlong ; This an invalid index (8)
384 b aaLhbrx ; This for lhbrx
385 b aaPassAlong ; This an invalid index (A)
386 b aaSthbrx ; This for sthbrx
387 b aaDcbz ; This for dcbz
388 b aaPassAlong ; This an invalid index (D)
389 b aaPassAlong ; This an invalid index (E)
390 b aaPassAlong ; This an invalid index (F)
391
392
393;
394; Here we handle the set up for the lmw and stmw. After that, we split off to the
395; individual routines.
396;
397; Note also that after some set up, all of the string instructions come through here as well.
398;
399 .align 5
400
401aaLmwStmw:
402 rlwinm r17,r18,31,1,29 ; Convert doublword based index to words
403 li r28,0 ; Set no extra bytes to move (used for string instructions)
404 subfic r17,r17,32*4 ; Calculate the length of the transfer
405
406aaLSComm: addi r19,r13,saver0+4 ; Offset to registers in savearea
407 mr r16,r23 ; Make a hunk pointer
408
409 bt iUpdate,aaStmw ; This is the stmw...
410
411;
412; Load multiple word
413;
414
415aaLmwNxt: cmplwi cr1,r17,8*4 ; Is there enough to move 8?
416 blt- cr1,aaLmwNxtH ; Not enough for a full hunk...
417 subi r17,r17,8*4 ; Back off for another hunk
418
419 crset cr0_eq ; Set this to see if we failed
420 mtmsr r22 ; Flip DR, RI
421 isync
422
423 lwz r2,0(r16) ; Load word 0
424 bf- cr0_eq,aaLmwB1 ; Error, bail...
425 lwz r15,4(r16) ; Load word 1
426 bf- cr0_eq,aaLmwB1 ; Error, bail...
427 lwz r14,8(r16) ; Load word 2
428 bf- cr0_eq,aaLmwB1 ; Error, bail...
429 lwz r5,12(r16) ; Load word 3
430 bf- cr0_eq,aaLmwB1 ; Error, bail...
431 lwz r6,16(r16) ; Load word 4
432 bf- cr0_eq,aaLmwB1 ; Error, bail...
433 lwz r7,20(r16) ; Load word 5
434 bf- cr0_eq,aaLmwB1 ; Error, bail...
435 lwz r8,24(r16) ; Load word 6
436 bf- cr0_eq,aaLmwB1 ; Error, bail...
437 lwz r9,28(r16) ; Load word 7
438
439aaLmwB1: mr r4,r0 ; Remember DAR, jus in case we failed the access
440 mtmsr r30 ; Turn off DR, RI
441 isync
442
443 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
444
445 addi r16,r16,8*4 ; Point up to next input aread
446
447 stwx r2,r19,r18 ; Store register
448 addi r18,r18,8 ; Next register
449 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
450 stwx r15,r19,r18 ; Store register
451 addi r18,r18,8 ; Next register
452 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
453 stwx r14,r19,r18 ; Store register
454 addi r18,r18,8 ; Next register
455 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
456 stwx r5,r19,r18 ; Store register
457 addi r18,r18,8 ; Next register
458 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
459 stwx r6,r19,r18 ; Store register
460 addi r18,r18,8 ; Next register
461 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
462 stwx r7,r19,r18 ; Store register
463 addi r18,r18,8 ; Next register
464 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
465 stwx r8,r19,r18 ; Store register
466 addi r18,r18,8 ; Next register
467 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
468 stwx r9,r19,r18 ; Store register
469 addi r18,r18,8 ; Next register
470 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
471
472 b aaLmwNxt ; Do the next hunk...
473
474 .align 5
475
476aaLmwNxtH: cmplwi cr1,r17,4*4 ; Do we have 4 left?
477 blt cr1,aaLmwL4 ; Nope...
478
479 subi r17,r17,4*4 ; Set count properly
480
481 crset cr0_eq ; Set this to see if we failed
482 mtmsr r22 ; Flip DR, RI, and maybe PR on
483 isync
484
485 lwz r2,0(r16) ; Load word 0
486 bf- cr0_eq,aaLmwB2 ; Error, bail...
487 lwz r15,4(r16) ; Load word 1
488 bf- cr0_eq,aaLmwB2 ; Error, bail...
489 lwz r14,8(r16) ; Load word 2
490 bf- cr0_eq,aaLmwB2 ; Error, bail...
491 lwz r5,12(r16) ; Load word 3
492
493aaLmwB2: mr r4,r0 ; Remember DAR, jus in case we failed the access
494 mtmsr r30 ; Turn off DR, RI
495 isync
496
497 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
498
499 addi r16,r16,4*4 ; Point up to next input aread
500
501 stwx r2,r19,r18 ; Store register
502 addi r18,r18,8 ; Next register
503 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
504 stwx r15,r19,r18 ; Store register
505 addi r18,r18,8 ; Next register
506 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
507 stwx r14,r19,r18 ; Store register
508 addi r18,r18,8 ; Next register
509 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
510 stwx r5,r19,r18 ; Store register
511 addi r18,r18,8 ; Next register
512 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
513
514aaLmwL4: or. r5,r17,r28 ; Do we have anything left?
515 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three full words left?
516 cmplwi cr2,r17,0 ; Do we have no full words left?
517 beq aaComExit ; Nothing left...
518
519 crset cr0_eq ; Set this to see if we failed
520 mtmsr r22 ; Flip DR, RI, and maybe PR on
521 isync
522
523 beq- cr2,aaLmwBy ; No full words, get bytes...
524
525 lwz r2,0(r16) ; Pick up first word
526 bf- cr0_eq,aaLmwDn ; Read failed, escape...
527 addi r16,r16,4 ; Next input location
528 blt cr1,aaLmwBy ; We only had one, we are done...
529
530 lwz r15,0(r16) ; Pick up second word
531 bf- cr0_eq,aaLmwDn ; Read failed, escape...
532 addi r16,r16,4 ; Next input location
533 beq cr1,aaLmwBy ; We had two, we are done...
534
535 lwz r14,0(r16) ; Load word 3
536 addi r16,r16,4 ; Next input location
537
538aaLmwBy: cmplwi cr2,r28,0 ; Any trailing bytes to do?
539 li r8,0 ; Clear second trailing byte
540 cmplwi cr1,r28,2 ; Check for 1, 2, or 3
541 li r9,0 ; Clear third trailing byte
542 beq+ cr2,aaLmwDn ; No trailing bytes...
543
544 lbz r5,0(r16) ; Pick up first trailing byte
545 bf- cr0_eq,aaLmwDn ; Read failed, escape...
546 blt cr1,aaLmwDn ; We only had one, we are done...
547
548 lbz r8,1(r16) ; Pick up second trailing byte
549 bf- cr0_eq,aaLmwDn ; Read failed, escape...
550 beq cr1,aaLmwDn ; We had two, we are done...
551
552 lbz r9,2(r16) ; Get last trailing byte
553
554
555aaLmwDn: rlwinm r5,r5,24,0,7 ; Move first byte to top
556 cmplwi cr2,r17,0 ; Any full words to do?
557 mr r4,r0 ; Remember DAR, just in case we failed the access
558 rlwimi r9,r8,8,16,23 ; Move second byte above third byte
559 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three full words left?
560 mr r3,r30 ; Set the normal MSR
561 rlwimi r5,r9,8,8,23 ; Move bytes 1 and 2 after 0
562
563 mtmsr r30 ; Turn off DR, RI
564 isync
565
566 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
567
568 beq- cr2,aaLmwCb ; No full words, copy bytes...
569
570 stwx r2,r19,r18 ; Store register
571 addi r18,r18,8 ; Next register
572 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
573 blt cr1,aaLmwCb ; We only had one, we are done...
574
575 stwx r15,r19,r18 ; Store register
576 addi r18,r18,8 ; Next register
577 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
578 beq cr1,aaLmwCb ; We had two, we are done...
579
580 stwx r14,r19,r18 ; Store register
581 addi r18,r18,8 ; Next register
582 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
583
584aaLmwCb: mr. r28,r28 ; Any trailing bytes to do?
585 beq+ aaComExit ; Nope, leave...
586
587 stwx r5,r19,r18 ; Store register
588
589 b aaComExit ; We are done....
590
591;
592; Store multiple word
593;
594
595 .align 5
596
597aaStmw:
598 crclr iUpdate ; Make sure we do not think this is an update form
599
600aaStmwNxt: cmplwi cr1,r17,8*4 ; Is there enough to move 8?
601 blt- cr1,aaStmwNxtH ; Not enough for a full hunk...
602 subi r17,r17,8*4 ; Back off for another hunk
603
604 lwzx r2,r19,r18 ; Store register
605 addi r18,r18,8 ; Next register
606 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
607 lwzx r15,r19,r18 ; Store register
608 addi r18,r18,8 ; Next register
609 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
610 lwzx r14,r19,r18 ; Store register
611 addi r18,r18,8 ; Next register
612 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
613 lwzx r5,r19,r18 ; Store register
614 addi r18,r18,8 ; Next register
615 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
616 lwzx r6,r19,r18 ; Store register
617 addi r18,r18,8 ; Next register
618 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
619 lwzx r7,r19,r18 ; Store register
620 addi r18,r18,8 ; Next register
621 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
622 lwzx r8,r19,r18 ; Store register
623 addi r18,r18,8 ; Next register
624 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
625 lwzx r9,r19,r18 ; Store register
626 addi r18,r18,8 ; Next register
627 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
628
629 crset cr0_eq ; Set this to see if we failed
630 mtmsr r22 ; Flip DR, RI, and maybe PR on
631 isync
632
633 stw r2,0(r16) ; Store word 0
634 bf- cr0_eq,aaStmwB1 ; Error, bail...
635 stw r15,4(r16) ; Store word 1
636 bf- cr0_eq,aaStmwB1 ; Error, bail...
637 stw r14,8(r16) ; Store word 2
638 bf- cr0_eq,aaStmwB1 ; Error, bail...
639 stw r5,12(r16) ; Store word 3
640 bf- cr0_eq,aaStmwB1 ; Error, bail...
641 stw r6,16(r16) ; Store word 4
642 bf- cr0_eq,aaStmwB1 ; Error, bail...
643 stw r7,20(r16) ; Store word 5
644 bf- cr0_eq,aaStmwB1 ; Error, bail...
645 stw r8,24(r16) ; Store word 6
646 bf- cr0_eq,aaStmwB1 ; Error, bail...
647 stw r9,28(r16) ; Store word 7
648
649 addi r16,r16,8*4 ; Point up to next output aread
650
651
652aaStmwB1: mr r4,r0 ; Remember DAR, jus in case we failed the access
653 mtmsr r30 ; Normal MSR
654 isync
655
656 bt- cr0_eq,aaStmwNxt ; We have more to do and no failed access...
657 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
658
659 .align 5
660
661aaStmwNxtH: cmplwi cr1,r17,(4*4) ; Do we have at least 4 left?
662 blt cr1,aaStmwL4 ; Nope...
663 subi r17,r17,4*4 ; Set count properly
664
665 lwzx r2,r19,r18 ; Store register
666 addi r18,r18,8 ; Next register
667 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
668 lwzx r15,r19,r18 ; Store register
669 addi r18,r18,8 ; Next register
670 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
671 lwzx r14,r19,r18 ; Store register
672 addi r18,r18,8 ; Next register
673 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
674 lwzx r5,r19,r18 ; Store register
675 addi r18,r18,8 ; Next register
676 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
677
678 crset cr0_eq ; Set this to see if we failed
679 mtmsr r22 ; Flip DR, RI
680 isync
681
682 stw r2,0(r16) ; Store word 0
683 bf- cr0_eq,aaStmwB2 ; Error, bail...
684 stw r15,4(r16) ; Store word 1
685 bf- cr0_eq,aaStmwB2 ; Error, bail...
686 stw r14,8(r16) ; Store word 2
687 bf- cr0_eq,aaStmwB2 ; Error, bail...
688 stw r5,12(r16) ; Store word 3
689
690 addi r16,r16,4*4 ; Point up to next input aread
691
692aaStmwB2: mr r4,r0 ; Remember DAR, jus in case we failed the access
693 mtmsr r30 ; Normal MSR
694 isync
695
696 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
697
698aaStmwL4: or. r5,r17,r28 ; Do we have anything left to do?
699 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three left?
700 cmplwi cr2,r17,0 ; Do we have no full words left?
701 beq aaComExit ; Nothing left...
702
703 beq- cr2,aaStmwBy1 ; No full words, check out bytes
704
705 lwzx r2,r19,r18 ; Store register
706 addi r18,r18,8 ; Next register
707 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
708 blt cr1,aaStmwBy1 ; We only had one, go save it...
709
710 lwzx r15,r19,r18 ; Store register
711 addi r18,r18,8 ; Next register
712 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
713 beq cr1,aaStmwBy1 ; We had two, go save it...
714
715 lwzx r14,r19,r18 ; Store register
716 addi r18,r18,8 ; Next register
717 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
718
719aaStmwBy1: mr. r28,r28 ; Do we have any trailing bytes?
720 beq+ aaStmwSt ; Nope...
721
722 lwzx r5,r19,r18 ; Yes, pick up one extra register
723
724aaStmwSt: crset cr0_eq ; Set this to see if we failed
725 mtmsr r22 ; Flip DR, RI
726 isync
727
728 beq- cr2,aaStmwBy2 ; No words, check trailing bytes...
729
730 stw r2,0(r16) ; Save first word
731 bf- cr0_eq,aaStmwDn ; Store failed, escape...
732 addi r16,r16,4 ; Bump sink
733 blt cr1,aaStmwBy2 ; We only had one, we are done...
734
735 stw r15,0(r16) ; Save second word
736 bf- cr0_eq,aaStmwDn ; Store failed, escape...
737 addi r16,r16,4 ; Bump sink
738 beq cr1,aaStmwBy2 ; We had two, we are done...
739
740 stw r14,0(r16) ; Save third word
741 bf- cr0_eq,aaStmwDn ; Store failed, escape...
742 addi r16,r16,4 ; Bump sink
743
744aaStmwBy2: rlwinm r2,r5,8,24,31 ; Get byte 0
745 cmplwi cr2,r28,0 ; Any trailing bytes to do?
746 rlwinm r14,r5,24,24,31 ; Get byte 3
747 li r8,0 ; Clear second trailing byte
748 cmplwi cr1,r28,2 ; Check for 1, 2, or 3
749 li r9,0 ; Clear third trailing byte
750 beq+ cr2,aaStmwDn ; No trailing bytes...
751 rlwinm r15,r5,16,24,31 ; Get byte 1
752
753 stb r2,0(r16) ; Save first byte
754 bf- cr0_eq,aaStmwDn ; Read failed, escape...
755 blt cr1,aaStmwDn ; We only had one, we are done...
756
757 stb r15,1(r16) ; Save second byte
758 bf- cr0_eq,aaStmwDn ; Read failed, escape...
759 beq cr1,aaStmwDn ; We had two, we are done...
760
761 stb r14,2(r16) ; Save third byte
762
763aaStmwDn: mr r4,r0 ; Remember DAR, jus in case we failed the access
764 mtmsr r30 ; Normal MSR
765 isync
766
767 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
768
769 b aaComExit ; We are done....
770
771
772;
773; Load String Indexed
774;
775
776 .align 5
777
778aaLswx: lwz r17,savexer+4(r13) ; Pick up the XER
779 crclr iUpdate ; Make sure we think this the load form
780 rlwinm. r25,r17,0,25,31 ; Get the number of bytes to load
781 rlwinm r28,r17,0,30,31 ; Get the number of bytes past an even word
782 beq- aaComExit ; Do nothing if 0 length...
783 xor r17,r25,r28 ; Round down to an even word boundary
784 b aaLSComm ; Join up with common load/store code...
785
786
787;
788; Load String Immediate
789;
790
791 .align 5
792
793aaLswi: mr r9,r23 ; Save the DAR
794 bl eIFetch ; Get the instruction image
795 bne- eRedriveAsISI ; Go redrive this as an ISI...
796 rlwinm r25,r10,21,27,31 ; Get the number of bytes to load
797 crclr iUpdate ; Make sure we think this the load form
798 subi r25,r25,1 ; Back off by 1
799 rlwinm r25,r25,0,27,31 ; Clear back down
800 addi r25,r25,1 ; Add back the 1 to convert 0 to 32
801 rlwinm r28,r25,0,30,31 ; Get the number of bytes past an even word
802 xor r17,r25,r28 ; Round down to an even word boundary
803 mr r23,r9 ; Move back the DAR
804 b aaLSComm ; Join up with common load/store code...
805
806;
807; Store String Indexed
808;
809
810 .align 5
811
812aaStswx: lwz r17,savexer+4(r13) ; Pick up the XER
813 crclr iUpdate ; Make sure this is clear in case we have 0 length
814 rlwinm. r25,r17,0,25,31 ; Get the number of bytes to load
815 rlwinm r28,r17,0,30,31 ; Get the number of bytes past an even word
816 beq- aaComExit ; Do nothing if 0 length...
817 xor r17,r25,r28 ; Round down to an even word boundary
818 crset iUpdate ; Make sure we think this the store form
819 b aaLSComm ; Join up with common load/store code...
820
821
822;
823; Store String Immediate
824;
825
826 .align 5
827
828aaStswi: mr r9,r23 ; Save the DAR
829 bl eIFetch ; Get the instruction image
830 bne- eRedriveAsISI ; Go redrive this as an ISI...
831 rlwinm r25,r10,21,27,31 ; Get the number of bytes to load
832 crclr iUpdate ; Make sure we think this the load form
833 subi r25,r25,1 ; Back off by 1
834 rlwinm r25,r25,0,27,31 ; Clear back down
835 addi r25,r25,1 ; Add back the 1 to convert 0 to 32
836 rlwinm r28,r25,21,30,31 ; Get the number of bytes past an even word
837 xor r17,r25,r28 ; Round down to an even word boundary
838 mr r23,r9 ; Move back the DAR
839 b aaLSComm ; Join up with common load/store code...
840
841
842;
843; Load byte-reversed word
844;
845
846 .align 5
847
848aaLwbrx:
849 add r18,r18,r13 ; Index to source register
850
851 crset cr0_eq ; Set this to see if we failed
852 mtmsr r22 ; Flip DR, RI, and maybe PR on
853 isync
854
855 lwz r11,0(r23) ; Load the word
856
857 mr r4,r0 ; Save the DAR if we failed the access
858 mtmsr r30 ; Restore normal MSR
859 isync
860
861 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
862
863 rlwinm r10,r11,8,0,31 ; Get byte 0 to 3 and byte 2 to 1
864 rlwimi r10,r11,24,16,23 ; Move byte 1 to byte 2
865 rlwimi r10,r11,24,0,7 ; Move byte 3 to byte 0
866
867 stw r10,saver0+4(r18) ; Set the register
868
869 b aaComExit ; All done, go exit...
870
871
872
873;
874; Store byte-reversed word
875;
876
877 .align 5
878
879aaStwbrx:
880 add r18,r18,r13 ; Index to source register
881 lwz r11,saver0+4(r18) ; Get the register to store
882
883 rlwinm r10,r11,8,0,31 ; Get byte 0 to 3 and byte 2 to 1
884 rlwimi r10,r11,24,16,23 ; Move byte 1 to byte 2
885 rlwimi r10,r11,24,0,7 ; Move byte 3 to byte 0
886
887 crset cr0_eq ; Set this to see if we failed
888 mtmsr r22 ; Flip DR, RI, and maybe PR on
889 isync
890
891 stw r10,0(r23) ; Store the reversed halfword
892
893 mr r4,r0 ; Save the DAR if we failed the access
894 mtmsr r30 ; Restore normal MSR
895 isync
896
897 bt+ cr0_eq,aaComExit ; All done, go exit...
898 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
899
900
901
902;
903; Load byte-reversed halfword
904;
905
906 .align 5
907
908aaLhbrx:
909 add r18,r18,r13 ; Index to source register
910
911 crset cr0_eq ; Set this to see if we failed
912 mtmsr r22 ; Flip DR, RI, and maybe PR on
913 isync
914
915 lhz r11,0(r23) ; Load the halfword
916
917 mr r4,r0 ; Save the DAR if we failed the access
918 mtmsr r30 ; Restore normal MSR
919 isync
920
921 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
922
923 rlwinm r10,r11,8,16,23 ; Rotate bottom byte up one and clear everything else
924 rlwimi r10,r11,24,24,31 ; Put old second from bottom into bottom
925
926 stw r10,saver0+4(r18) ; Set the register
927
928 b aaComExit ; All done, go exit...
929
930
931;
932; Store byte-reversed halfword
933;
934
935 .align 5
936
937aaSthbrx:
938 add r18,r18,r13 ; Index to source register
939 lwz r10,saver0+4(r18) ; Get the register to store
940 rlwinm r10,r10,8,0,31 ; Rotate bottom byte up one
941 rlwimi r10,r10,16,24,31 ; Put old second from bottom into bottom
942
943 crset cr0_eq ; Set this to see if we failed
944 mtmsr r22 ; Flip DR, RI, and maybe PR on
945 isync
946
947 sth r10,0(r23) ; Store the reversed halfword
948
949 mr r4,r0 ; Save the DAR if we failed the access
950 mtmsr r30 ; Restore normal MSR
951 isync
952
953 bt+ cr0_eq,aaComExit ; All done, go exit...
954 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
955
956;
957; Data cache block zero
958;
959
960 .align 5
961
962aaDcbz:
963 lwz r0,savesrr0+4(r13) ; get instruction address
964 li r4,_COMM_PAGE_BASE_ADDRESS
965 rlwinm r23,r23,0,0,26 ; Round EA back to a 32-byte boundary
966 sub r4,r0,r4 ; compute instruction offset from base of commpage
967 cmplwi r4,_COMM_PAGE_AREA_USED ; did fault occur in commpage?
968 bge+ aaDcbz1 ; skip if not in commpage
969 lwz r4,savecr(r13) ; if we take a dcbz in the commpage...
970 rlwinm r4,r4,0,0,27 ; ...clear users cr7 as a flag for commpage code
971 stw r4,savecr(r13)
972aaDcbz1:
973 crset cr0_eq ; Set this to see if we failed
974 li r0,0 ; Clear this out
975 mtmsr r22 ; Flip DR, RI, and maybe PR on
976 isync
977
978 stw r0,0(r23) ; Clear word
979 bne- aaDcbzXit ; Got DSI, we are stopping...
980 stw r0,4(r23) ; Clear word
981 bne- aaDcbzXit ; Got DSI, we are stopping...
982 stw r0,8(r23) ; Clear word
983 bne- aaDcbzXit ; Got DSI, we are stopping...
984 stw r0,12(r23) ; Clear word
985 bne- aaDcbzXit ; Got DSI, we are stopping...
986 stw r0,16(r23) ; Clear word
987 bne- aaDcbzXit ; Got DSI, we are stopping...
988 stw r0,20(r23) ; Clear word
989 bne- aaDcbzXit ; Got DSI, we are stopping...
990 stw r0,24(r23) ; Clear word
991 bne- aaDcbzXit ; Got DSI, we are stopping...
992 stw r0,28(r23) ; Clear word
993
994aaDcbzXit: mr r4,r0 ; Save the DAR if we failed the access
995 mtmsr r30 ; Restore normal MSR
996 isync
997
998 crclr iUpdate ; Make sure we do not think this is an update form
999
1000 bt+ cr0_eq,aaComExit ; All done, go exit...
1001 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
1002
1003
1004;
1005; Unhandled alignment exception, pass it along
1006;
1007
1008aaPassAlong:
1009 li r0,1 ; Indicate that we failed to emulate
1010 stw r0,savemisc3(r13) ; Assume that we emulate ok
1011 b EXT(EmulExit)
1012
1013
1014
1015
1016;
1017; We go here to emulate a trace exception after we have handled alignment error
1018;
1019
1020 .align 5
1021
1022aaComExitrd:
1023 oris r9,r9,hi16(SAVredrive) ; Set the redrive bit
1024 li r11,T_TRACE ; Set trace interrupt
1025 rlwinm r12,r12,0,16,31 ; Clear top half of SRR1
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...
1029
1030
1031
1032;
1033; Redrive as a DSI
1034
1035aaRedriveAsDSI:
1036 mr r20,r1 ; Save the DSISR
1037 mr r21,r4
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...
1046
1047
1048
1049;
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.
1056;
1057
1058 .align 10 ; Make sure we are on a 1k boundary
1059 .globl EXT(aaFPopTable)
1060
1061LEXT(aaFPopTable)
1062 lfs f0,emfp0(r31) ; Load single variant
1063 blr
1064
1065 stfs f0,emfp0(r31) ; Store single variant
1066 blr
1067
1068 lfd f0,emfp0(r31) ; Load double variant
1069 blr
1070
1071 stfd f0,emfp0(r31) ; Store double variant
1072 blr
1073
1074 lfs f1,emfp0(r31) ; Load single variant
1075 blr
1076
1077 stfs f1,emfp0(r31) ; Store single variant
1078 blr
1079
1080 lfd f1,emfp0(r31) ; Load double variant
1081 blr
1082
1083 stfd f1,emfp0(r31) ; Store double variant
1084 blr
1085
1086 lfs f2,emfp0(r31) ; Load single variant
1087 blr
1088
1089 stfs f2,emfp0(r31) ; Store single variant
1090 blr
1091
1092 lfd f2,emfp0(r31) ; Load double variant
1093 blr
1094
1095 stfd f2,emfp0(r31) ; Store double variant
1096 blr
1097
1098 lfs f3,emfp0(r31) ; Load single variant
1099 blr
1100
1101 stfs f3,emfp0(r31) ; Store single variant
1102 blr
1103
1104 lfd f3,emfp0(r31) ; Load double variant
1105 blr
1106
1107 stfd f3,emfp0(r31) ; Store double variant
1108 blr
1109
1110 lfs f4,emfp0(r31) ; Load single variant
1111 blr
1112
1113 stfs f4,emfp0(r31) ; Store single variant
1114 blr
1115
1116 lfd f4,emfp0(r31) ; Load double variant
1117 blr
1118
1119 stfd f4,emfp0(r31) ; Store double variant
1120 blr
1121
1122 lfs f5,emfp0(r31) ; Load single variant
1123 blr
1124
1125 stfs f5,emfp0(r31) ; Store single variant
1126 blr
1127
1128 lfd f5,emfp0(r31) ; Load double variant
1129 blr
1130
1131 stfd f5,emfp0(r31) ; Store double variant
1132 blr
1133
1134 lfs f6,emfp0(r31) ; Load single variant
1135 blr
1136
1137 stfs f6,emfp0(r31) ; Store single variant
1138 blr
1139
1140 lfd f6,emfp0(r31) ; Load double variant
1141 blr
1142
1143 stfd f6,emfp0(r31) ; Store double variant
1144 blr
1145
1146 lfs f7,emfp0(r31) ; Load single variant
1147 blr
1148
1149 stfs f7,emfp0(r31) ; Store single variant
1150 blr
1151
1152 lfd f7,emfp0(r31) ; Load double variant
1153 blr
1154
1155 stfd f7,emfp0(r31) ; Store double variant
1156 blr
1157
1158 lfs f8,emfp0(r31) ; Load single variant
1159 blr
1160
1161 stfs f8,emfp0(r31) ; Store single variant
1162 blr
1163
1164 lfd f8,emfp0(r31) ; Load double variant
1165 blr
1166
1167 stfd f8,emfp0(r31) ; Store double variant
1168 blr
1169
1170 lfs f9,emfp0(r31) ; Load single variant
1171 blr
1172
1173 stfs f9,emfp0(r31) ; Store single variant
1174 blr
1175
1176 lfd f9,emfp0(r31) ; Load double variant
1177 blr
1178
1179 stfd f9,emfp0(r31) ; Store double variant
1180 blr
1181
1182 lfs f10,emfp0(r31) ; Load single variant
1183 blr
1184
1185 stfs f10,emfp0(r31) ; Store single variant
1186 blr
1187
1188 lfd f10,emfp0(r31) ; Load double variant
1189 blr
1190
1191 stfd f10,emfp0(r31) ; Store double variant
1192 blr
1193
1194 lfs f11,emfp0(r31) ; Load single variant
1195 blr
1196
1197 stfs f11,emfp0(r31) ; Store single variant
1198 blr
1199
1200 lfd f11,emfp0(r31) ; Load double variant
1201 blr
1202
1203 stfd f11,emfp0(r31) ; Store double variant
1204 blr
1205
1206 lfs f12,emfp0(r31) ; Load single variant
1207 blr
1208
1209 stfs f12,emfp0(r31) ; Store single variant
1210 blr
1211
1212 lfd f12,emfp0(r31) ; Load double variant
1213 blr
1214
1215 stfd f12,emfp0(r31) ; Store double variant
1216 blr
1217
1218 lfs f13,emfp0(r31) ; Load single variant
1219 blr
1220
1221 stfs f13,emfp0(r31) ; Store single variant
1222 blr
1223
1224 lfd f13,emfp0(r31) ; Load double variant
1225 blr
1226
1227 stfd f13,emfp0(r31) ; Store double variant
1228 blr
1229
1230 lfs f14,emfp0(r31) ; Load single variant
1231 blr
1232
1233 stfs f14,emfp0(r31) ; Store single variant
1234 blr
1235
1236 lfd f14,emfp0(r31) ; Load double variant
1237 blr
1238
1239 stfd f14,emfp0(r31) ; Store double variant
1240 blr
1241
1242 lfs f15,emfp0(r31) ; Load single variant
1243 blr
1244
1245 stfs f15,emfp0(r31) ; Store single variant
1246 blr
1247
1248 lfd f15,emfp0(r31) ; Load double variant
1249 blr
1250
1251 stfd f15,emfp0(r31) ; Store double variant
1252 blr
1253
1254 lfs f16,emfp0(r31) ; Load single variant
1255 blr
1256
1257 stfs f16,emfp0(r31) ; Store single variant
1258 blr
1259
1260 lfd f16,emfp0(r31) ; Load double variant
1261 blr
1262
1263 stfd f16,emfp0(r31) ; Store double variant
1264 blr
1265
1266 lfs f17,emfp0(r31) ; Load single variant
1267 blr
1268
1269 stfs f17,emfp0(r31) ; Store single variant
1270 blr
1271
1272 lfd f17,emfp0(r31) ; Load double variant
1273 blr
1274
1275 stfd f17,emfp0(r31) ; Store double variant
1276 blr
1277
1278 lfs f18,emfp0(r31) ; Load single variant
1279 blr
1280
1281 stfs f18,emfp0(r31) ; Store single variant
1282 blr
1283
1284 lfd f18,emfp0(r31) ; Load double variant
1285 blr
1286
1287 stfd f18,emfp0(r31) ; Store double variant
1288 blr
1289
1290 lfs f19,emfp0(r31) ; Load single variant
1291 blr
1292
1293 stfs f19,emfp0(r31) ; Store single variant
1294 blr
1295
1296 lfd f19,emfp0(r31) ; Load double variant
1297 blr
1298
1299 stfd f19,emfp0(r31) ; Store double variant
1300 blr
1301
1302 lfs f20,emfp0(r31) ; Load single variant
1303 blr
1304
1305 stfs f20,emfp0(r31) ; Store single variant
1306 blr
1307
1308 lfd f20,emfp0(r31) ; Load double variant
1309 blr
1310
1311 stfd f20,emfp0(r31) ; Store double variant
1312 blr
1313
1314 lfs f21,emfp0(r31) ; Load single variant
1315 blr
1316
1317 stfs f21,emfp0(r31) ; Store single variant
1318 blr
1319
1320 lfd f21,emfp0(r31) ; Load double variant
1321 blr
1322
1323 stfd f21,emfp0(r31) ; Store double variant
1324 blr
1325
1326 lfs f22,emfp0(r31) ; Load single variant
1327 blr
1328
1329 stfs f22,emfp0(r31) ; Store single variant
1330 blr
1331
1332 lfd f22,emfp0(r31) ; Load double variant
1333 blr
1334
1335 stfd f22,emfp0(r31) ; Store double variant
1336 blr
1337
1338 lfs f23,emfp0(r31) ; Load single variant
1339 blr
1340
1341 stfs f23,emfp0(r31) ; Store single variant
1342 blr
1343
1344 lfd f23,emfp0(r31) ; Load double variant
1345 blr
1346
1347 stfd f23,emfp0(r31) ; Store double variant
1348 blr
1349
1350 lfs f24,emfp0(r31) ; Load single variant
1351 blr
1352
1353 stfs f24,emfp0(r31) ; Store single variant
1354 blr
1355
1356 lfd f24,emfp0(r31) ; Load double variant
1357 blr
1358
1359 stfd f24,emfp0(r31) ; Store double variant
1360 blr
1361
1362 lfs f25,emfp0(r31) ; Load single variant
1363 blr
1364
1365 stfs f25,emfp0(r31) ; Store single variant
1366 blr
1367
1368 lfd f25,emfp0(r31) ; Load double variant
1369 blr
1370
1371 stfd f25,emfp0(r31) ; Store double variant
1372 blr
1373
1374 lfs f26,emfp0(r31) ; Load single variant
1375 blr
1376
1377 stfs f26,emfp0(r31) ; Store single variant
1378 blr
1379
1380 lfd f26,emfp0(r31) ; Load double variant
1381 blr
1382
1383 stfd f26,emfp0(r31) ; Store double variant
1384 blr
1385
1386 lfs f27,emfp0(r31) ; Load single variant
1387 blr
1388
1389 stfs f27,emfp0(r31) ; Store single variant
1390 blr
1391
1392 lfd f27,emfp0(r31) ; Load double variant
1393 blr
1394
1395 stfd f27,emfp0(r31) ; Store double variant
1396 blr
1397
1398 lfs f28,emfp0(r31) ; Load single variant
1399 blr
1400
1401 stfs f28,emfp0(r31) ; Store single variant
1402 blr
1403
1404 lfd f28,emfp0(r31) ; Load double variant
1405 blr
1406
1407 stfd f28,emfp0(r31) ; Store double variant
1408 blr
1409
1410 lfs f29,emfp0(r31) ; Load single variant
1411 blr
1412
1413 stfs f29,emfp0(r31) ; Store single variant
1414 blr
1415
1416 lfd f29,emfp0(r31) ; Load double variant
1417 blr
1418
1419 stfd f29,emfp0(r31) ; Store double variant
1420 blr
1421
1422 lfs f30,emfp0(r31) ; Load single variant
1423 blr
1424
1425 stfs f30,emfp0(r31) ; Store single variant
1426 blr
1427
1428 lfd f30,emfp0(r31) ; Load double variant
1429 blr
1430
1431 stfd f30,emfp0(r31) ; Store double variant
1432 blr
1433
1434 lfs f31,emfp0(r31) ; Load single variant
1435 blr
1436
1437 stfs f31,emfp0(r31) ; Store single variant
1438 blr
1439
1440 lfd f31,emfp0(r31) ; Load double variant
1441 blr
1442
1443 stfd f31,emfp0(r31) ; Store double variant
1444 blr
1445