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 1446