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