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