xnu-1228.3.13.tar.gz
[apple/xnu.git] / osfmk / ppc / Emulate.s
0 / 1445 (  0%)
CommitLineData
1/*
2 * Copyright (c) 2000-2007 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
70LEXT(Emulate)
71
72 bf-- pf64Bitb,emn64 ; Skip if not 64-bit
73 b EXT(Emulate64) ; Jump to the 64-bit code...
74
75emn64: 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
91eNoVect: 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
126eZeroBase: lwzx r22,r24,r22 ; Get the index value
127 add r22,r22,r19 ; Get DAR
128 b eFinishUp ; Done, go finish up...
129
130eNotIndex: 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
142eFinishUp: 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
149eExit: 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; R1 has the DSISR if access failed.
156;
157
158 .align 5
159
160eIFetch: lwz r23,savesrr1+4(r13) ; Get old MSR
161 mflr r28 ; Save return
162
163 rlwinm r3,r23,32-MSR_DR_BIT+MSR_IR_BIT,MSR_DR_BIT,MSR_DR_BIT ; Move IR to DR for ifetch
164 mfmsr r30 ; Save the MSR for now
165 rlwimi r3,r23,32-MSR_RI_BIT+MSR_DR_BIT,MSR_RI_BIT,MSR_RI_BIT ; Move DR to RI for ifetch
166
167 lwz r23,savesrr0+4(r13) ; Get instruction address
168 or r3,r23,r3 ; Turn on the DR and RI bit if translation was on
169
170 crset cr0_eq ; Set this to see if we failed
171 mtmsr r3 ; Flip RI and, if IR was set, DR
172 isync
173
174 lwz r10,0(r23) ; Fetch the instruction
175
176 mtmsr r30 ; Trans and RI off
177 isync
178
179 mtlr r28 ; Restore the LR
180 blr ; Return with instruction image in R10
181
182
183;
184; Redrive as an ISI
185;
186
187eRedriveAsISI:
188 lwz r6,savesrr1+4(r13) ; Get the srr1 value
189 lwz r4,SAVflags(r13) ; Pick up the flags
190 li r11,T_INSTRUCTION_ACCESS ; Set failing instruction fetch code
191 rlwimi r6,r1,0,1,4 ; Move the DSISR bits to the SRR1
192 oris r4,r4,hi16(SAVredrive) ; Set the redrive bit
193 stw r11,saveexception(r13) ; Set the replacement code
194 stw r4,SAVflags(r13) ; Set redrive request
195 stw r6,savesrr1+4(r13) ; Set the srr1 value
196 b EXT(EmulExit) ; Bail out to handle ISI...
197
198
199;
200; This code emulates instructions that have failed because of operand
201; alignment. We decode the DSISR to figure out what we need to do.
202;
203; DSISR:
204; 0001FC00 - Instruction designation
205#define iFloat 12
206#define iOptype1 15
207#define iOptype2 16
208#define iOptype3 18
209#define iOptype4 19
210#define iUpdate 17
211#define iStore 20
212#define iDouble 21
213#define iNotify 22
214; 000003E0 - Target/Source register
215; 0000001F - Register to update if update form
216;
217
218 .align 5
219 .globl EXT(AlignAssist)
220
221LEXT(AlignAssist)
222 bf-- pf64Bitb,aan64 ; Skip if not 64-bit
223 b EXT(AlignAssist64) ; Jump to the 64-bit code...
224
225aan64: lwz r20,savedsisr(r13) ; Get the DSISR
226 li r0,0 ; Assume we emulate
227 mfsprg r31,0 ; Get the per_proc
228 mtcrf 0x10,r20 ; Put instruction ID in CR for later
229 lwz r21,spcFlags(r31) ; Grab the special flags
230 stw r0,savemisc3(r13) ; Assume that we emulate ok
231 mtcrf 0x08,r20 ; Put instruction ID in CR for later
232 rlwinm. r0,r21,0,runningVMbit,runningVMbit ; Are we running a VM?
233 mtcrf 0x04,r20 ; Put instruction ID in CR for later
234 lwz r22,savesrr1+4(r13) ; Get the SRR1
235 bne- aaPassAlong ; We are in a VM, no emulation for alignment exceptions...
236 lwz r19,dgFlags(0) ; Get the diagnostics flags
237 crxor iFloat,iOptype1,iOptype2 ; Set this to 0 if both bits are either 0 or 1
238 mr r26,r20 ; Save the DSISR
239 rlwinm. r0,r22,0,MSR_SE_BIT,MSR_SE_BIT ; Were we single stepping?
240 lwz r23,savedar+4(r13) ; Pick up the address that we want to access
241 crnot traceInst,cr0_eq ; Remember if trace is on
242
243 rlwinm. r0,r19,0,enaNotifyEMb,enaNotifyEMb ; Should we notify that an alignment exception happened?
244 mfmsr r30 ; Save the MSR for now
245 crnot iNotify,cr0_eq ; Remember to tell someone we did this
246 li r29,emfp0 ; Point to work area
247 crxor iFloat,iFloat,iOptype3 ; Set true if we have a floating point instruction
248 dcbz r29,r31 ; Clear and allocate a cache line for us to work in
249 rlwinm r24,r20,3,24,28 ; Get displacement to register to update if update form
250 rlwimi r20,r20,24,28,28 ; Move load/store indication to the bottom of index
251 rlwinm r22,r22,0,MSR_DR_BIT,MSR_DR_BIT ; Move rupt DR to DR for ifetch
252 rlwimi r20,r20,26,27,27 ; Move single/double indication to just above the bottom
253 rlwimi r22,r22,32-MSR_RI_BIT+MSR_DR_BIT,MSR_RI_BIT,MSR_RI_BIT ; Move DR to RI for i-fetch
254 lis r29,hi16(EXT(aaFPopTable)) ; High part of FP branch table
255 or r22,r30,r22 ; Set the DR and RI bits if translation was on
256 bf- iFloat,aaNotFloat ; This is not a floating point instruction...
257 ori r29,r29,lo16(EXT(aaFPopTable)) ; Low part of FP branch table
258
259 rlwimi r29,r20,0,22,28 ; Index into table based upon register||iDouble||iStore
260 mtctr r29 ; Get set to call the function
261 bt iStore,aaFPstore ; This is an FP store...
262
263;
264; Here we handle floating point loads
265;
266
267aaFPload: crset cr0_eq ; Set this to see if we failed
268 mtmsr r22 ; Flip DR, RI
269 isync
270
271 lwz r10,0(r23) ; Get the first word
272 bf- cr0_eq,aaLdNotDbl ; Jump out if we DSIed...
273 bf iDouble,aaLdNotDbl ; this is not a double...
274 lwz r11,4(r23) ; Get the second half
275
276aaLdNotDbl: mr r4,r0 ; Save the DAR if we failed the access
277
278 mtmsr r30 ; Turn off translation again
279 isync
280
281 bf- cr0_eq,aaRedriveAsDSI ; Go redrive this as a DSI...
282
283 stw r10,emfp0(r31) ; Save the first half
284 stw r11,emfp0+4(r31) ; Save the second half, just in case we need it
285
286 bctrl ; Go set the target FP register
287
288 b aaComExit ; All done, go exit...
289
290;
291; Here we handle floating point stores
292;
293
294 .align 5
295
296aaFPstore: bctrl ; Go save the source FP register
297
298 lwz r10,emfp0(r31) ; Get first word
299 crandc iDouble,iDouble,iOptype4 ; Change to 4-byte access if stfiwx
300 lwz r11,emfp0+4(r31) ; and the second
301 bf+ iOptype4,aaNotstfiwx ; This is not a stfiwx...
302 mr r10,r11 ; The stfiwx wants to store the second half
303
304aaNotstfiwx:
305 crset cr0_eq ; Set this to see if we failed
306 mtmsr r22 ; Flip DR, RI
307 isync
308
309 stw r10,0(r23) ; Save the first word
310 bf- cr0_eq,aaStNotDbl ; Jump out if we DSIed...
311 bf iDouble,aaStNotDbl ; this is not a double...
312 stw r11,4(r23) ; Save the second half
313
314aaStNotDbl: mr r4,r0 ; Save the DAR if we failed the access
315 mtmsr r30 ; Turn off
316 isync
317
318 bf- cr0_eq,aaRedriveAsDSI ; Go redrive this as a DSI...
319
320;
321; Common exit routines
322;
323
324aaComExit: lwz r10,savesrr0+4(r13) ; Get the failing instruction address
325 add r24,r24,r13 ; Offset to update register
326 li r11,T_IN_VAIN ; Assume we are all done
327 addi r10,r10,4 ; Step to the next instruction
328 bf iUpdate,aaComExNU ; Skip if not an update form...
329 stw r23,saver0+4(r24) ; Update the target
330
331aaComExNU: lwz r9,SAVflags(r13) ; Get the flags
332 stw r10,savesrr0+4(r13) ; Set new PC
333 bt- traceInst,aaComExitrd ; We are tracing, go emulate trace...
334 bf+ iNotify,aaComExGo ; Nothing special here, go...
335
336 li r11,T_ALIGNMENT ; Set the we just did an alignment exception....
337
338aaComExGo: b EXT(EmulExit) ; We are done, no tracing on...
339
340
341;
342; This is not a floating point operation
343;
344; The table of these emulation routines is indexed by taking the low order 4 bits of
345; the instruction code in the DSISR and subtracting 7. If this comes up negative,
346; the instruction is not to be emulated. Then we add bit 0 of the code * 4. This
347; gives us a fairly compact and almost unique index. Both lwm and stmw map to 0 so
348; that one needs to be further reduced, and we end up with holes at a few indexes.
349;
350
351 .align 5
352
353aaNotFloat:
354 lis r19,hi16(aaEmTable) ; Point to high part of table address
355 rlwinm r3,r26,24,26,29 ; Isolate last 4 bits of op type * 4
356 rlwimi r19,r26,20,27,27 ; Get bit 0 of instruction code * 4 into bottom of table base
357 addic. r3,r3,-28 ; Subtract 7*4 to adjust index
358 ori r19,r19,lo16(aaEmTable) ; Low part of table address
359 blt- aaPassAlong ; We do not handle any of these (lwarx, stwcx., eciwx, ecowx)...
360 add r19,r19,r3 ; Point to emulation routine
361 rlwinm r18,r26,30,24,28 ; Get the target/source register displacement
362
363 mtctr r19 ; Set the routine address
364
365 bctr ; Go emulate the instruction...
366
367;
368; This is the table of non-floating point emulation routines.
369; It is indexed by the code immediately above.
370
371 .align 5
372
373aaEmTable:
374 b aaLmwStmw ; This for lmw/stmw
375 b aaLswx ; This for lwwx
376 b aaLswi ; This for lswi
377 b aaStswx ; This for stswx
378 b aaStswi ; This for stswi
379 b aaLwbrx ; This for lwbrx
380 b aaPassAlong ; This an invalid index (6)
381 b aaStwbrx ; This for stwbrx
382 b aaPassAlong ; This an invalid index (8)
383 b aaLhbrx ; This for lhbrx
384 b aaPassAlong ; This an invalid index (A)
385 b aaSthbrx ; This for sthbrx
386 b aaDcbz ; This for dcbz
387 b aaPassAlong ; This an invalid index (D)
388 b aaPassAlong ; This an invalid index (E)
389 b aaPassAlong ; This an invalid index (F)
390
391
392;
393; Here we handle the set up for the lmw and stmw. After that, we split off to the
394; individual routines.
395;
396; Note also that after some set up, all of the string instructions come through here as well.
397;
398 .align 5
399
400aaLmwStmw:
401 rlwinm r17,r18,31,1,29 ; Convert doublword based index to words
402 li r28,0 ; Set no extra bytes to move (used for string instructions)
403 subfic r17,r17,32*4 ; Calculate the length of the transfer
404
405aaLSComm: addi r19,r13,saver0+4 ; Offset to registers in savearea
406 mr r16,r23 ; Make a hunk pointer
407
408 bt iUpdate,aaStmw ; This is the stmw...
409
410;
411; Load multiple word
412;
413
414aaLmwNxt: cmplwi cr1,r17,8*4 ; Is there enough to move 8?
415 blt- cr1,aaLmwNxtH ; Not enough for a full hunk...
416 subi r17,r17,8*4 ; Back off for another hunk
417
418 crset cr0_eq ; Set this to see if we failed
419 mtmsr r22 ; Flip DR, RI
420 isync
421
422 lwz r2,0(r16) ; Load word 0
423 bf- cr0_eq,aaLmwB1 ; Error, bail...
424 lwz r15,4(r16) ; Load word 1
425 bf- cr0_eq,aaLmwB1 ; Error, bail...
426 lwz r14,8(r16) ; Load word 2
427 bf- cr0_eq,aaLmwB1 ; Error, bail...
428 lwz r5,12(r16) ; Load word 3
429 bf- cr0_eq,aaLmwB1 ; Error, bail...
430 lwz r6,16(r16) ; Load word 4
431 bf- cr0_eq,aaLmwB1 ; Error, bail...
432 lwz r7,20(r16) ; Load word 5
433 bf- cr0_eq,aaLmwB1 ; Error, bail...
434 lwz r8,24(r16) ; Load word 6
435 bf- cr0_eq,aaLmwB1 ; Error, bail...
436 lwz r9,28(r16) ; Load word 7
437
438aaLmwB1: mr r4,r0 ; Remember DAR, jus in case we failed the access
439 mtmsr r30 ; Turn off DR, RI
440 isync
441
442 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
443
444 addi r16,r16,8*4 ; Point up to next input aread
445
446 stwx r2,r19,r18 ; Store register
447 addi r18,r18,8 ; Next register
448 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
449 stwx r15,r19,r18 ; Store register
450 addi r18,r18,8 ; Next register
451 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
452 stwx r14,r19,r18 ; Store register
453 addi r18,r18,8 ; Next register
454 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
455 stwx r5,r19,r18 ; Store register
456 addi r18,r18,8 ; Next register
457 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
458 stwx r6,r19,r18 ; Store register
459 addi r18,r18,8 ; Next register
460 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
461 stwx r7,r19,r18 ; Store register
462 addi r18,r18,8 ; Next register
463 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
464 stwx r8,r19,r18 ; Store register
465 addi r18,r18,8 ; Next register
466 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
467 stwx r9,r19,r18 ; Store register
468 addi r18,r18,8 ; Next register
469 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
470
471 b aaLmwNxt ; Do the next hunk...
472
473 .align 5
474
475aaLmwNxtH: cmplwi cr1,r17,4*4 ; Do we have 4 left?
476 blt cr1,aaLmwL4 ; Nope...
477
478 subi r17,r17,4*4 ; Set count properly
479
480 crset cr0_eq ; Set this to see if we failed
481 mtmsr r22 ; Flip DR, RI, and maybe PR on
482 isync
483
484 lwz r2,0(r16) ; Load word 0
485 bf- cr0_eq,aaLmwB2 ; Error, bail...
486 lwz r15,4(r16) ; Load word 1
487 bf- cr0_eq,aaLmwB2 ; Error, bail...
488 lwz r14,8(r16) ; Load word 2
489 bf- cr0_eq,aaLmwB2 ; Error, bail...
490 lwz r5,12(r16) ; Load word 3
491
492aaLmwB2: mr r4,r0 ; Remember DAR, jus in case we failed the access
493 mtmsr r30 ; Turn off DR, RI
494 isync
495
496 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
497
498 addi r16,r16,4*4 ; Point up to next input aread
499
500 stwx r2,r19,r18 ; Store register
501 addi r18,r18,8 ; Next register
502 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
503 stwx r15,r19,r18 ; Store register
504 addi r18,r18,8 ; Next register
505 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
506 stwx r14,r19,r18 ; Store register
507 addi r18,r18,8 ; Next register
508 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
509 stwx r5,r19,r18 ; Store register
510 addi r18,r18,8 ; Next register
511 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
512
513aaLmwL4: or. r5,r17,r28 ; Do we have anything left?
514 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three full words left?
515 cmplwi cr2,r17,0 ; Do we have no full words left?
516 beq aaComExit ; Nothing left...
517
518 crset cr0_eq ; Set this to see if we failed
519 mtmsr r22 ; Flip DR, RI, and maybe PR on
520 isync
521
522 beq- cr2,aaLmwBy ; No full words, get bytes...
523
524 lwz r2,0(r16) ; Pick up first word
525 bf- cr0_eq,aaLmwDn ; Read failed, escape...
526 addi r16,r16,4 ; Next input location
527 blt cr1,aaLmwBy ; We only had one, we are done...
528
529 lwz r15,0(r16) ; Pick up second word
530 bf- cr0_eq,aaLmwDn ; Read failed, escape...
531 addi r16,r16,4 ; Next input location
532 beq cr1,aaLmwBy ; We had two, we are done...
533
534 lwz r14,0(r16) ; Load word 3
535 addi r16,r16,4 ; Next input location
536
537aaLmwBy: cmplwi cr2,r28,0 ; Any trailing bytes to do?
538 li r8,0 ; Clear second trailing byte
539 cmplwi cr1,r28,2 ; Check for 1, 2, or 3
540 li r9,0 ; Clear third trailing byte
541 beq+ cr2,aaLmwDn ; No trailing bytes...
542
543 lbz r5,0(r16) ; Pick up first trailing byte
544 bf- cr0_eq,aaLmwDn ; Read failed, escape...
545 blt cr1,aaLmwDn ; We only had one, we are done...
546
547 lbz r8,1(r16) ; Pick up second trailing byte
548 bf- cr0_eq,aaLmwDn ; Read failed, escape...
549 beq cr1,aaLmwDn ; We had two, we are done...
550
551 lbz r9,2(r16) ; Get last trailing byte
552
553
554aaLmwDn: rlwinm r5,r5,24,0,7 ; Move first byte to top
555 cmplwi cr2,r17,0 ; Any full words to do?
556 mr r4,r0 ; Remember DAR, just in case we failed the access
557 rlwimi r9,r8,8,16,23 ; Move second byte above third byte
558 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three full words left?
559 mr r3,r30 ; Set the normal MSR
560 rlwimi r5,r9,8,8,23 ; Move bytes 1 and 2 after 0
561
562 mtmsr r30 ; Turn off DR, RI
563 isync
564
565 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
566
567 beq- cr2,aaLmwCb ; No full words, copy bytes...
568
569 stwx r2,r19,r18 ; Store register
570 addi r18,r18,8 ; Next register
571 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
572 blt cr1,aaLmwCb ; We only had one, we are done...
573
574 stwx r15,r19,r18 ; Store register
575 addi r18,r18,8 ; Next register
576 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
577 beq cr1,aaLmwCb ; We had two, we are done...
578
579 stwx r14,r19,r18 ; Store register
580 addi r18,r18,8 ; Next register
581 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
582
583aaLmwCb: mr. r28,r28 ; Any trailing bytes to do?
584 beq+ aaComExit ; Nope, leave...
585
586 stwx r5,r19,r18 ; Store register
587
588 b aaComExit ; We are done....
589
590;
591; Store multiple word
592;
593
594 .align 5
595
596aaStmw:
597 crclr iUpdate ; Make sure we do not think this is an update form
598
599aaStmwNxt: cmplwi cr1,r17,8*4 ; Is there enough to move 8?
600 blt- cr1,aaStmwNxtH ; Not enough for a full hunk...
601 subi r17,r17,8*4 ; Back off for another hunk
602
603 lwzx r2,r19,r18 ; Store register
604 addi r18,r18,8 ; Next register
605 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
606 lwzx r15,r19,r18 ; Store register
607 addi r18,r18,8 ; Next register
608 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
609 lwzx r14,r19,r18 ; Store register
610 addi r18,r18,8 ; Next register
611 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
612 lwzx r5,r19,r18 ; Store register
613 addi r18,r18,8 ; Next register
614 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
615 lwzx r6,r19,r18 ; Store register
616 addi r18,r18,8 ; Next register
617 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
618 lwzx r7,r19,r18 ; Store register
619 addi r18,r18,8 ; Next register
620 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
621 lwzx r8,r19,r18 ; Store register
622 addi r18,r18,8 ; Next register
623 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
624 lwzx r9,r19,r18 ; Store register
625 addi r18,r18,8 ; Next register
626 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
627
628 crset cr0_eq ; Set this to see if we failed
629 mtmsr r22 ; Flip DR, RI, and maybe PR on
630 isync
631
632 stw r2,0(r16) ; Store word 0
633 bf- cr0_eq,aaStmwB1 ; Error, bail...
634 stw r15,4(r16) ; Store word 1
635 bf- cr0_eq,aaStmwB1 ; Error, bail...
636 stw r14,8(r16) ; Store word 2
637 bf- cr0_eq,aaStmwB1 ; Error, bail...
638 stw r5,12(r16) ; Store word 3
639 bf- cr0_eq,aaStmwB1 ; Error, bail...
640 stw r6,16(r16) ; Store word 4
641 bf- cr0_eq,aaStmwB1 ; Error, bail...
642 stw r7,20(r16) ; Store word 5
643 bf- cr0_eq,aaStmwB1 ; Error, bail...
644 stw r8,24(r16) ; Store word 6
645 bf- cr0_eq,aaStmwB1 ; Error, bail...
646 stw r9,28(r16) ; Store word 7
647
648 addi r16,r16,8*4 ; Point up to next output aread
649
650
651aaStmwB1: mr r4,r0 ; Remember DAR, jus in case we failed the access
652 mtmsr r30 ; Normal MSR
653 isync
654
655 bt- cr0_eq,aaStmwNxt ; We have more to do and no failed access...
656 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
657
658 .align 5
659
660aaStmwNxtH: cmplwi cr1,r17,(4*4) ; Do we have at least 4 left?
661 blt cr1,aaStmwL4 ; Nope...
662 subi r17,r17,4*4 ; Set count properly
663
664 lwzx r2,r19,r18 ; Store register
665 addi r18,r18,8 ; Next register
666 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
667 lwzx r15,r19,r18 ; Store register
668 addi r18,r18,8 ; Next register
669 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
670 lwzx r14,r19,r18 ; Store register
671 addi r18,r18,8 ; Next register
672 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
673 lwzx r5,r19,r18 ; Store register
674 addi r18,r18,8 ; Next register
675 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
676
677 crset cr0_eq ; Set this to see if we failed
678 mtmsr r22 ; Flip DR, RI
679 isync
680
681 stw r2,0(r16) ; Store word 0
682 bf- cr0_eq,aaStmwB2 ; Error, bail...
683 stw r15,4(r16) ; Store word 1
684 bf- cr0_eq,aaStmwB2 ; Error, bail...
685 stw r14,8(r16) ; Store word 2
686 bf- cr0_eq,aaStmwB2 ; Error, bail...
687 stw r5,12(r16) ; Store word 3
688
689 addi r16,r16,4*4 ; Point up to next input aread
690
691aaStmwB2: mr r4,r0 ; Remember DAR, jus in case we failed the access
692 mtmsr r30 ; Normal MSR
693 isync
694
695 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
696
697aaStmwL4: or. r5,r17,r28 ; Do we have anything left to do?
698 cmplwi cr1,r17,(2*4) ; Do we have one, two, or three left?
699 cmplwi cr2,r17,0 ; Do we have no full words left?
700 beq aaComExit ; Nothing left...
701
702 beq- cr2,aaStmwBy1 ; No full words, check out bytes
703
704 lwzx r2,r19,r18 ; Store register
705 addi r18,r18,8 ; Next register
706 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
707 blt cr1,aaStmwBy1 ; We only had one, go save it...
708
709 lwzx r15,r19,r18 ; Store register
710 addi r18,r18,8 ; Next register
711 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
712 beq cr1,aaStmwBy1 ; We had two, go save it...
713
714 lwzx r14,r19,r18 ; Store register
715 addi r18,r18,8 ; Next register
716 rlwinm r18,r18,0,24,28 ; Wrap back to 0 if needed
717
718aaStmwBy1: mr. r28,r28 ; Do we have any trailing bytes?
719 beq+ aaStmwSt ; Nope...
720
721 lwzx r5,r19,r18 ; Yes, pick up one extra register
722
723aaStmwSt: crset cr0_eq ; Set this to see if we failed
724 mtmsr r22 ; Flip DR, RI
725 isync
726
727 beq- cr2,aaStmwBy2 ; No words, check trailing bytes...
728
729 stw r2,0(r16) ; Save first word
730 bf- cr0_eq,aaStmwDn ; Store failed, escape...
731 addi r16,r16,4 ; Bump sink
732 blt cr1,aaStmwBy2 ; We only had one, we are done...
733
734 stw r15,0(r16) ; Save second word
735 bf- cr0_eq,aaStmwDn ; Store failed, escape...
736 addi r16,r16,4 ; Bump sink
737 beq cr1,aaStmwBy2 ; We had two, we are done...
738
739 stw r14,0(r16) ; Save third word
740 bf- cr0_eq,aaStmwDn ; Store failed, escape...
741 addi r16,r16,4 ; Bump sink
742
743aaStmwBy2: rlwinm r2,r5,8,24,31 ; Get byte 0
744 cmplwi cr2,r28,0 ; Any trailing bytes to do?
745 rlwinm r14,r5,24,24,31 ; Get byte 3
746 li r8,0 ; Clear second trailing byte
747 cmplwi cr1,r28,2 ; Check for 1, 2, or 3
748 li r9,0 ; Clear third trailing byte
749 beq+ cr2,aaStmwDn ; No trailing bytes...
750 rlwinm r15,r5,16,24,31 ; Get byte 1
751
752 stb r2,0(r16) ; Save first byte
753 bf- cr0_eq,aaStmwDn ; Read failed, escape...
754 blt cr1,aaStmwDn ; We only had one, we are done...
755
756 stb r15,1(r16) ; Save second byte
757 bf- cr0_eq,aaStmwDn ; Read failed, escape...
758 beq cr1,aaStmwDn ; We had two, we are done...
759
760 stb r14,2(r16) ; Save third byte
761
762aaStmwDn: mr r4,r0 ; Remember DAR, jus in case we failed the access
763 mtmsr r30 ; Normal MSR
764 isync
765
766 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
767
768 b aaComExit ; We are done....
769
770
771;
772; Load String Indexed
773;
774
775 .align 5
776
777aaLswx: lwz r17,savexer+4(r13) ; Pick up the XER
778 crclr iUpdate ; Make sure we think this the load form
779 rlwinm. r25,r17,0,25,31 ; Get the number of bytes to load
780 rlwinm r28,r17,0,30,31 ; Get the number of bytes past an even word
781 beq- aaComExit ; Do nothing if 0 length...
782 xor r17,r25,r28 ; Round down to an even word boundary
783 b aaLSComm ; Join up with common load/store code...
784
785
786;
787; Load String Immediate
788;
789
790 .align 5
791
792aaLswi: mr r9,r23 ; Save the DAR
793 bl eIFetch ; Get the instruction image
794 bne- eRedriveAsISI ; Go redrive this as an ISI...
795 rlwinm r25,r10,21,27,31 ; Get the number of bytes to load
796 crclr iUpdate ; Make sure we think this the load form
797 subi r25,r25,1 ; Back off by 1
798 rlwinm r25,r25,0,27,31 ; Clear back down
799 addi r25,r25,1 ; Add back the 1 to convert 0 to 32
800 rlwinm r28,r25,0,30,31 ; Get the number of bytes past an even word
801 xor r17,r25,r28 ; Round down to an even word boundary
802 mr r23,r9 ; Move back the DAR
803 b aaLSComm ; Join up with common load/store code...
804
805;
806; Store String Indexed
807;
808
809 .align 5
810
811aaStswx: lwz r17,savexer+4(r13) ; Pick up the XER
812 crclr iUpdate ; Make sure this is clear in case we have 0 length
813 rlwinm. r25,r17,0,25,31 ; Get the number of bytes to load
814 rlwinm r28,r17,0,30,31 ; Get the number of bytes past an even word
815 beq- aaComExit ; Do nothing if 0 length...
816 xor r17,r25,r28 ; Round down to an even word boundary
817 crset iUpdate ; Make sure we think this the store form
818 b aaLSComm ; Join up with common load/store code...
819
820
821;
822; Store String Immediate
823;
824
825 .align 5
826
827aaStswi: mr r9,r23 ; Save the DAR
828 bl eIFetch ; Get the instruction image
829 bne- eRedriveAsISI ; Go redrive this as an ISI...
830 rlwinm r25,r10,21,27,31 ; Get the number of bytes to load
831 crclr iUpdate ; Make sure we think this the load form
832 subi r25,r25,1 ; Back off by 1
833 rlwinm r25,r25,0,27,31 ; Clear back down
834 addi r25,r25,1 ; Add back the 1 to convert 0 to 32
835 rlwinm r28,r25,21,30,31 ; Get the number of bytes past an even word
836 xor r17,r25,r28 ; Round down to an even word boundary
837 mr r23,r9 ; Move back the DAR
838 b aaLSComm ; Join up with common load/store code...
839
840
841;
842; Load byte-reversed word
843;
844
845 .align 5
846
847aaLwbrx:
848 add r18,r18,r13 ; Index to source register
849
850 crset cr0_eq ; Set this to see if we failed
851 mtmsr r22 ; Flip DR, RI, and maybe PR on
852 isync
853
854 lwz r11,0(r23) ; Load the word
855
856 mr r4,r0 ; Save the DAR if we failed the access
857 mtmsr r30 ; Restore normal MSR
858 isync
859
860 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
861
862 rlwinm r10,r11,8,0,31 ; Get byte 0 to 3 and byte 2 to 1
863 rlwimi r10,r11,24,16,23 ; Move byte 1 to byte 2
864 rlwimi r10,r11,24,0,7 ; Move byte 3 to byte 0
865
866 stw r10,saver0+4(r18) ; Set the register
867
868 b aaComExit ; All done, go exit...
869
870
871
872;
873; Store byte-reversed word
874;
875
876 .align 5
877
878aaStwbrx:
879 add r18,r18,r13 ; Index to source register
880 lwz r11,saver0+4(r18) ; Get the register to store
881
882 rlwinm r10,r11,8,0,31 ; Get byte 0 to 3 and byte 2 to 1
883 rlwimi r10,r11,24,16,23 ; Move byte 1 to byte 2
884 rlwimi r10,r11,24,0,7 ; Move byte 3 to byte 0
885
886 crset cr0_eq ; Set this to see if we failed
887 mtmsr r22 ; Flip DR, RI, and maybe PR on
888 isync
889
890 stw r10,0(r23) ; Store the reversed halfword
891
892 mr r4,r0 ; Save the DAR if we failed the access
893 mtmsr r30 ; Restore normal MSR
894 isync
895
896 bt+ cr0_eq,aaComExit ; All done, go exit...
897 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
898
899
900
901;
902; Load byte-reversed halfword
903;
904
905 .align 5
906
907aaLhbrx:
908 add r18,r18,r13 ; Index to source register
909
910 crset cr0_eq ; Set this to see if we failed
911 mtmsr r22 ; Flip DR, RI, and maybe PR on
912 isync
913
914 lhz r11,0(r23) ; Load the halfword
915
916 mr r4,r0 ; Save the DAR if we failed the access
917 mtmsr r30 ; Restore normal MSR
918 isync
919
920 bf- cr0_eq,aaRedriveAsDSI ; We failed, go redrive this as a DSI...
921
922 rlwinm r10,r11,8,16,23 ; Rotate bottom byte up one and clear everything else
923 rlwimi r10,r11,24,24,31 ; Put old second from bottom into bottom
924
925 stw r10,saver0+4(r18) ; Set the register
926
927 b aaComExit ; All done, go exit...
928
929
930;
931; Store byte-reversed halfword
932;
933
934 .align 5
935
936aaSthbrx:
937 add r18,r18,r13 ; Index to source register
938 lwz r10,saver0+4(r18) ; Get the register to store
939 rlwinm r10,r10,8,0,31 ; Rotate bottom byte up one
940 rlwimi r10,r10,16,24,31 ; Put old second from bottom into bottom
941
942 crset cr0_eq ; Set this to see if we failed
943 mtmsr r22 ; Flip DR, RI, and maybe PR on
944 isync
945
946 sth r10,0(r23) ; Store the reversed halfword
947
948 mr r4,r0 ; Save the DAR if we failed the access
949 mtmsr r30 ; Restore normal MSR
950 isync
951
952 bt+ cr0_eq,aaComExit ; All done, go exit...
953 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
954
955;
956; Data cache block zero
957;
958
959 .align 5
960
961aaDcbz:
962 lwz r0,savesrr0+4(r13) ; get instruction address
963 li r4,_COMM_PAGE_BASE_ADDRESS
964 rlwinm r23,r23,0,0,26 ; Round EA back to a 32-byte boundary
965 sub r4,r0,r4 ; compute instruction offset from base of commpage
966 cmplwi r4,_COMM_PAGE_AREA_USED ; did fault occur in commpage?
967 bge+ aaDcbz1 ; skip if not in commpage
968 lwz r4,savecr(r13) ; if we take a dcbz in the commpage...
969 rlwinm r4,r4,0,0,27 ; ...clear users cr7 as a flag for commpage code
970 stw r4,savecr(r13)
971aaDcbz1:
972 crset cr0_eq ; Set this to see if we failed
973 li r0,0 ; Clear this out
974 mtmsr r22 ; Flip DR, RI, and maybe PR on
975 isync
976
977 stw r0,0(r23) ; Clear word
978 bne- aaDcbzXit ; Got DSI, we are stopping...
979 stw r0,4(r23) ; Clear word
980 bne- aaDcbzXit ; Got DSI, we are stopping...
981 stw r0,8(r23) ; Clear word
982 bne- aaDcbzXit ; Got DSI, we are stopping...
983 stw r0,12(r23) ; Clear word
984 bne- aaDcbzXit ; Got DSI, we are stopping...
985 stw r0,16(r23) ; Clear word
986 bne- aaDcbzXit ; Got DSI, we are stopping...
987 stw r0,20(r23) ; Clear word
988 bne- aaDcbzXit ; Got DSI, we are stopping...
989 stw r0,24(r23) ; Clear word
990 bne- aaDcbzXit ; Got DSI, we are stopping...
991 stw r0,28(r23) ; Clear word
992
993aaDcbzXit: mr r4,r0 ; Save the DAR if we failed the access
994 mtmsr r30 ; Restore normal MSR
995 isync
996
997 crclr iUpdate ; Make sure we do not think this is an update form
998
999 bt+ cr0_eq,aaComExit ; All done, go exit...
1000 b aaRedriveAsDSI ; We failed, go redrive this as a DSI...
1001
1002
1003;
1004; Unhandled alignment exception, pass it along
1005;
1006
1007aaPassAlong:
1008 li r0,1 ; Indicate that we failed to emulate
1009 stw r0,savemisc3(r13) ; Assume that we emulate ok
1010 b EXT(EmulExit)
1011
1012
1013
1014
1015;
1016; We go here to emulate a trace exception after we have handled alignment error
1017;
1018
1019 .align 5
1020
1021aaComExitrd:
1022 lis r11,hi16(srr1clr) ; Get the bits we need to clear
1023 oris r9,r9,hi16(SAVredrive) ; Set the redrive bit
1024 andc r12,r12,r11 ; Clear what needs to be cleared
1025 li r11,T_TRACE ; Set trace interrupt
1026 stw r9,SAVflags(r13) ; Set the flags
1027 stw r11,saveexception(r13) ; Set the exception code
1028 b EXT(EmulExit) ; Exit and do trace interrupt...
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