llvm.org GIT mirror llvm / 9d760ae
This patch corrects logic in PPCFrameLowering for save and restore of nonvolatile condition register fields across calls under the SVR4 ABIs. * With the 64-bit ABI, the save location is at a fixed offset of 8 from the stack pointer. The frame pointer cannot be used to access this portion of the stack frame since the distance from the frame pointer may change with alloca calls. * With the 32-bit ABI, the save location is just below the general register save area, and is accessed via the frame pointer like the rest of the save areas. This is an optional slot, so it must only be created if any of CR2, CR3, and CR4 were modified. * For both ABIs, save/restore logic is generated only if one of the nonvolatile CR fields were modified. I also took this opportunity to clean up an extra FIXME in PPCFrameLowering.h. Save area offsets for 32-bit GPRs are meaningless for the 64-bit ABI, so I removed them for correctness and efficiency. Fixes PR13708 and partially also PR13623. It lets us enable exception handling on PPC64. Patch by William J. Schmidt! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163713 91177308-0d34-0410-b5e6-96231b3b80d8 Roman Divacky 7 years ago
5 changed file(s) with 326 addition(s) and 74 deletion(s). Raw diff Collapse all Expand all
1212
1313 #include "PPCFrameLowering.h"
1414 #include "PPCInstrInfo.h"
15 #include "PPCInstrBuilder.h"
1516 #include "PPCMachineFunctionInfo.h"
1617 #include "llvm/Function.h"
1718 #include "llvm/CodeGen/MachineFrameInfo.h"
167168 MI->eraseFromParent();
168169 }
169170
171 static bool spillsCR(const MachineFunction &MF) {
172 const PPCFunctionInfo *FuncInfo = MF.getInfo();
173 return FuncInfo->isCRSpilled();
174 }
175
170176 /// determineFrameLayout - Determine the size of the frame and maximum call
171177 /// frame size.
172178 void PPCFrameLowering::determineFrameLayout(MachineFunction &MF) const {
183189
184190 // If we are a leaf function, and use up to 224 bytes of stack space,
185191 // don't have a frame pointer, calls, or dynamic alloca then we do not need
186 // to adjust the stack pointer (we fit in the Red Zone).
192 // to adjust the stack pointer (we fit in the Red Zone). For 64-bit
193 // SVR4, we also require a stack frame if we need to spill the CR,
194 // since this spill area is addressed relative to the stack pointer.
187195 bool DisableRedZone = MF.getFunction()->hasFnAttr(Attribute::NoRedZone);
188 // FIXME SVR4 The 32-bit SVR4 ABI has no red zone.
196 // FIXME SVR4 The 32-bit SVR4 ABI has no red zone. However, it can
197 // still generate stackless code if all local vars are reg-allocated.
198 // Try: (FrameSize <= 224
199 // || (FrameSize == 0 && Subtarget.isPPC32 && Subtarget.isSVR4ABI()))
189200 if (!DisableRedZone &&
190201 FrameSize <= 224 && // Fits in red zone.
191202 !MFI->hasVarSizedObjects() && // No dynamic alloca.
192203 !MFI->adjustsStack() && // No calls.
204 !(Subtarget.isPPC64() && // No 64-bit SVR4 CRsave.
205 Subtarget.isSVR4ABI()
206 && spillsCR(MF)) &&
193207 (!ALIGN_STACK || MaxAlign <= TargetAlign)) { // No special alignment.
194208 // No need for frame
195209 MFI->setStackSize(0);
487501 // Add callee saved registers to move list.
488502 const std::vector &CSI = MFI->getCalleeSavedInfo();
489503 for (unsigned I = 0, E = CSI.size(); I != E; ++I) {
490 int Offset = MFI->getObjectOffset(CSI[I].getFrameIdx());
491504 unsigned Reg = CSI[I].getReg();
492505 if (Reg == PPC::LR || Reg == PPC::LR8 || Reg == PPC::RM) continue;
493506
496509 if (PPC::CRBITRCRegClass.contains(Reg))
497510 continue;
498511
512 // For SVR4, don't emit a move for the CR spill slot if we haven't
513 // spilled CRs.
514 if (Subtarget.isSVR4ABI()
515 && (PPC::CR2 <= Reg && Reg <= PPC::CR4)
516 && !spillsCR(MF))
517 continue;
518
519 // For 64-bit SVR4 when we have spilled CRs, the spill location
520 // is SP+8, not a frame-relative slot.
521 if (Subtarget.isSVR4ABI()
522 && Subtarget.isPPC64()
523 && (PPC::CR2 <= Reg && Reg <= PPC::CR4)) {
524 MachineLocation CSDst(PPC::X1, 8);
525 MachineLocation CSSrc(PPC::CR2);
526 Moves.push_back(MachineMove(Label, CSDst, CSSrc));
527 continue;
528 }
529
530 int Offset = MFI->getObjectOffset(CSI[I].getFrameIdx());
499531 MachineLocation CSDst(MachineLocation::VirtualFP, Offset);
500532 MachineLocation CSSrc(Reg);
501533 Moves.push_back(MachineMove(Label, CSDst, CSSrc));
713745 }
714746 }
715747
716 static bool spillsCR(const MachineFunction &MF) {
717 const PPCFunctionInfo *FuncInfo = MF.getInfo();
718 return FuncInfo->isCRSpilled();
719 }
720
721748 /// MustSaveLR - Return true if this function requires that we save the LR
722749 /// register onto the stack in the prolog and restore it in the epilog of the
723750 /// function.
807834 bool HasGPSaveArea = false;
808835 bool HasG8SaveArea = false;
809836 bool HasFPSaveArea = false;
810 bool HasCRSaveArea = false;
811837 bool HasVRSAVESaveArea = false;
812838 bool HasVRSaveArea = false;
813839
842868 if (Reg < MinFPR) {
843869 MinFPR = Reg;
844870 }
845 // FIXME SVR4: Disable CR save area for now.
846871 } else if (PPC::CRBITRCRegClass.contains(Reg) ||
847872 PPC::CRRCRegClass.contains(Reg)) {
848 // HasCRSaveArea = true;
873 ; // do nothing, as we already know whether CRs are spilled
849874 } else if (PPC::VRSAVERCRegClass.contains(Reg)) {
850875 HasVRSAVESaveArea = true;
851876 } else if (PPC::VRRCRegClass.contains(Reg)) {
925950 }
926951 }
927952
928 // The CR save area is below the general register save area.
929 if (HasCRSaveArea) {
930 // FIXME SVR4: Is it actually possible to have multiple elements in CSI
931 // which have the CR/CRBIT register class?
953 // For 32-bit only, the CR save area is below the general register
954 // save area. For 64-bit SVR4, the CR save area is addressed relative
955 // to the stack pointer and hence does not need an adjustment here.
956 // Only CR2 (the first nonvolatile spilled) has an associated frame
957 // index so that we have a single uniform save area.
958 if (spillsCR(MF) && !(Subtarget.isPPC64() && Subtarget.isSVR4ABI())) {
932959 // Adjust the frame index of the CR spill slot.
933960 for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
934961 unsigned Reg = CSI[i].getReg();
935962
936 if (PPC::CRBITRCRegClass.contains(Reg) ||
937 PPC::CRRCRegClass.contains(Reg)) {
963 if ((Subtarget.isSVR4ABI() && Reg == PPC::CR2)
964 // Leave Darwin logic as-is.
965 || (!Subtarget.isSVR4ABI() &&
966 (PPC::CRBITRCRegClass.contains(Reg) ||
967 PPC::CRRCRegClass.contains(Reg)))) {
938968 int FI = CSI[i].getFrameIdx();
939969
940970 FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
9721002 }
9731003 }
9741004 }
1005
1006 bool
1007 PPCFrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
1008 MachineBasicBlock::iterator MI,
1009 const std::vector &CSI,
1010 const TargetRegisterInfo *TRI) const {
1011
1012 // Currently, this function only handles SVR4 32- and 64-bit ABIs.
1013 // Return false otherwise to maintain pre-existing behavior.
1014 if (!Subtarget.isSVR4ABI())
1015 return false;
1016
1017 MachineFunction *MF = MBB.getParent();
1018 const PPCInstrInfo &TII =
1019 *static_cast(MF->getTarget().getInstrInfo());
1020 DebugLoc DL;
1021 bool CRSpilled = false;
1022
1023 for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
1024 unsigned Reg = CSI[i].getReg();
1025 // CR2 through CR4 are the nonvolatile CR fields.
1026 bool IsCRField = PPC::CR2 <= Reg && Reg <= PPC::CR4;
1027
1028 if (CRSpilled && IsCRField)
1029 continue;
1030
1031 // Add the callee-saved register as live-in; it's killed at the spill.
1032 MBB.addLiveIn(Reg);
1033
1034 // Insert the spill to the stack frame.
1035 if (IsCRField) {
1036 CRSpilled = true;
1037 // The first time we see a CR field, store the whole CR into the
1038 // save slot via GPR12 (available in the prolog for 32- and 64-bit).
1039 if (Subtarget.isPPC64()) {
1040 // 64-bit: SP+8
1041 MBB.insert(MI, BuildMI(*MF, DL, TII.get(PPC::MFCR), PPC::X12));
1042 MBB.insert(MI, BuildMI(*MF, DL, TII.get(PPC::STW))
1043 .addReg(PPC::X12,
1044 getKillRegState(true))
1045 .addImm(8)
1046 .addReg(PPC::X1));
1047 } else {
1048 // 32-bit: FP-relative. Note that we made sure CR2-CR4 all have
1049 // the same frame index in PPCRegisterInfo::hasReservedSpillSlot.
1050 MBB.insert(MI, BuildMI(*MF, DL, TII.get(PPC::MFCR), PPC::R12));
1051 MBB.insert(MI, addFrameReference(BuildMI(*MF, DL, TII.get(PPC::STW))
1052 .addReg(PPC::R12,
1053 getKillRegState(true)),
1054 CSI[i].getFrameIdx()));
1055 }
1056
1057 // Record that we spill the CR in this function.
1058 PPCFunctionInfo *FuncInfo = MF->getInfo();
1059 FuncInfo->setSpillsCR();
1060 } else {
1061 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
1062 TII.storeRegToStackSlot(MBB, MI, Reg, true,
1063 CSI[i].getFrameIdx(), RC, TRI);
1064 }
1065 }
1066 return true;
1067 }
1068
1069 static void
1070 restoreCRs(bool isPPC64, bool CR2Spilled, bool CR3Spilled, bool CR4Spilled,
1071 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
1072 const std::vector &CSI, unsigned CSIIndex) {
1073
1074 MachineFunction *MF = MBB.getParent();
1075 const PPCInstrInfo &TII =
1076 *static_cast(MF->getTarget().getInstrInfo());
1077 DebugLoc DL;
1078 unsigned RestoreOp, MoveReg;
1079
1080 if (isPPC64) {
1081 // 64-bit: SP+8
1082 MBB.insert(MI, BuildMI(*MF, DL, TII.get(PPC::LWZ), PPC::X12)
1083 .addImm(8)
1084 .addReg(PPC::X1));
1085 RestoreOp = PPC::MTCRF8;
1086 MoveReg = PPC::X12;
1087 } else {
1088 // 32-bit: FP-relative
1089 MBB.insert(MI, addFrameReference(BuildMI(*MF, DL, TII.get(PPC::LWZ),
1090 PPC::R12),
1091 CSI[CSIIndex].getFrameIdx()));
1092 RestoreOp = PPC::MTCRF;
1093 MoveReg = PPC::R12;
1094 }
1095
1096 if (CR2Spilled)
1097 MBB.insert(MI, BuildMI(*MF, DL, TII.get(RestoreOp), PPC::CR2)
1098 .addReg(MoveReg));
1099
1100 if (CR3Spilled)
1101 MBB.insert(MI, BuildMI(*MF, DL, TII.get(RestoreOp), PPC::CR3)
1102 .addReg(MoveReg));
1103
1104 if (CR4Spilled)
1105 MBB.insert(MI, BuildMI(*MF, DL, TII.get(RestoreOp), PPC::CR4)
1106 .addReg(MoveReg));
1107 }
1108
1109 bool
1110 PPCFrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
1111 MachineBasicBlock::iterator MI,
1112 const std::vector &CSI,
1113 const TargetRegisterInfo *TRI) const {
1114
1115 // Currently, this function only handles SVR4 32- and 64-bit ABIs.
1116 // Return false otherwise to maintain pre-existing behavior.
1117 if (!Subtarget.isSVR4ABI())
1118 return false;
1119
1120 MachineFunction *MF = MBB.getParent();
1121 const PPCInstrInfo &TII =
1122 *static_cast(MF->getTarget().getInstrInfo());
1123 bool CR2Spilled = false;
1124 bool CR3Spilled = false;
1125 bool CR4Spilled = false;
1126 unsigned CSIIndex = 0;
1127
1128 // Initialize insertion-point logic; we will be restoring in reverse
1129 // order of spill.
1130 MachineBasicBlock::iterator I = MI, BeforeI = I;
1131 bool AtStart = I == MBB.begin();
1132
1133 if (!AtStart)
1134 --BeforeI;
1135
1136 for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
1137 unsigned Reg = CSI[i].getReg();
1138
1139 if (Reg == PPC::CR2) {
1140 CR2Spilled = true;
1141 // The spill slot is associated only with CR2, which is the
1142 // first nonvolatile spilled. Save it here.
1143 CSIIndex = i;
1144 continue;
1145 } else if (Reg == PPC::CR3) {
1146 CR3Spilled = true;
1147 continue;
1148 } else if (Reg == PPC::CR4) {
1149 CR4Spilled = true;
1150 continue;
1151 } else {
1152 // When we first encounter a non-CR register after seeing at
1153 // least one CR register, restore all spilled CRs together.
1154 if ((CR2Spilled || CR3Spilled || CR4Spilled)
1155 && !(PPC::CR2 <= Reg && Reg <= PPC::CR4)) {
1156 restoreCRs(Subtarget.isPPC64(), CR2Spilled, CR3Spilled, CR4Spilled,
1157 MBB, I, CSI, CSIIndex);
1158 CR2Spilled = CR3Spilled = CR4Spilled = false;
1159 }
1160
1161 // Default behavior for non-CR saves.
1162 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
1163 TII.loadRegFromStackSlot(MBB, I, Reg, CSI[i].getFrameIdx(),
1164 RC, TRI);
1165 assert(I != MBB.begin() &&
1166 "loadRegFromStackSlot didn't insert any code!");
1167 }
1168
1169 // Insert in reverse order.
1170 if (AtStart)
1171 I = MBB.begin();
1172 else {
1173 I = BeforeI;
1174 ++I;
1175 }
1176 }
1177
1178 // If we haven't yet spilled the CRs, do so now.
1179 if (CR2Spilled || CR3Spilled || CR4Spilled)
1180 restoreCRs(Subtarget.isPPC64(), CR2Spilled, CR3Spilled, CR4Spilled,
1181 MBB, I, CSI, CSIIndex);
1182
1183 return true;
1184 }
1185
4343 void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
4444 RegScavenger *RS = NULL) const;
4545 void processFunctionBeforeFrameFinalized(MachineFunction &MF) const;
46
47 bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
48 MachineBasicBlock::iterator MI,
49 const std::vector &CSI,
50 const TargetRegisterInfo *TRI) const;
51
52 bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
53 MachineBasicBlock::iterator MI,
54 const std::vector &CSI,
55 const TargetRegisterInfo *TRI) const;
4656
4757 /// targetHandlesStackFrameRounding - Returns true if the target is
4858 /// responsible for rounding up the stack frame (probably at emitPrologue
169179 {PPC::R15, -68},
170180 {PPC::R14, -72},
171181
172 // CR save area offset.
173 // FIXME SVR4: Disable CR save area for now.
174 // {PPC::CR2, -4},
175 // {PPC::CR3, -4},
176 // {PPC::CR4, -4},
177 // {PPC::CR2LT, -4},
178 // {PPC::CR2GT, -4},
179 // {PPC::CR2EQ, -4},
180 // {PPC::CR2UN, -4},
181 // {PPC::CR3LT, -4},
182 // {PPC::CR3GT, -4},
183 // {PPC::CR3EQ, -4},
184 // {PPC::CR3UN, -4},
185 // {PPC::CR4LT, -4},
186 // {PPC::CR4GT, -4},
187 // {PPC::CR4EQ, -4},
188 // {PPC::CR4UN, -4},
182 // CR save area offset. We map each of the nonvolatile CR fields
183 // to the slot for CR2, which is the first of the nonvolatile CR
184 // fields to be assigned, so that we only allocate one save slot.
185 // See PPCRegisterInfo::hasReservedSpillSlot() for more information.
186 {PPC::CR2, -4},
189187
190188 // VRSAVE save area offset.
191189 {PPC::VRSAVE, -4},
227225 {PPC::F14, -144},
228226
229227 // General register save area offsets.
230 // FIXME 64-bit SVR4: Are 32-bit registers actually allocated in 64-bit
231 // mode?
232 {PPC::R31, -4},
233 {PPC::R30, -12},
234 {PPC::R29, -20},
235 {PPC::R28, -28},
236 {PPC::R27, -36},
237 {PPC::R26, -44},
238 {PPC::R25, -52},
239 {PPC::R24, -60},
240 {PPC::R23, -68},
241 {PPC::R22, -76},
242 {PPC::R21, -84},
243 {PPC::R20, -92},
244 {PPC::R19, -100},
245 {PPC::R18, -108},
246 {PPC::R17, -116},
247 {PPC::R16, -124},
248 {PPC::R15, -132},
249 {PPC::R14, -140},
250
251228 {PPC::X31, -8},
252229 {PPC::X30, -16},
253230 {PPC::X29, -24},
267244 {PPC::X15, -136},
268245 {PPC::X14, -144},
269246
270 // CR save area offset.
271 // FIXME SVR4: Disable CR save area for now.
272 // {PPC::CR2, -4},
273 // {PPC::CR3, -4},
274 // {PPC::CR4, -4},
275 // {PPC::CR2LT, -4},
276 // {PPC::CR2GT, -4},
277 // {PPC::CR2EQ, -4},
278 // {PPC::CR2UN, -4},
279 // {PPC::CR3LT, -4},
280 // {PPC::CR3GT, -4},
281 // {PPC::CR3EQ, -4},
282 // {PPC::CR3UN, -4},
283 // {PPC::CR4LT, -4},
284 // {PPC::CR4GT, -4},
285 // {PPC::CR4EQ, -4},
286 // {PPC::CR4UN, -4},
287
288247 // VRSAVE save area offset.
289248 {PPC::VRSAVE, -4},
290249
7070 : PPCGenRegisterInfo(ST.isPPC64() ? PPC::LR8 : PPC::LR,
7171 ST.isPPC64() ? 0 : 1,
7272 ST.isPPC64() ? 0 : 1),
73 Subtarget(ST), TII(tii) {
73 Subtarget(ST), TII(tii), CRSpillFrameIdx(0) {
7474 ImmToIdxMap[PPC::LD] = PPC::LDX; ImmToIdxMap[PPC::STD] = PPC::STDX;
7575 ImmToIdxMap[PPC::LBZ] = PPC::LBZX; ImmToIdxMap[PPC::STB] = PPC::STBX;
7676 ImmToIdxMap[PPC::LHZ] = PPC::LHZX; ImmToIdxMap[PPC::LHA] = PPC::LHAX;
109109 if (Subtarget.isDarwinABI())
110110 return Subtarget.isPPC64() ? CSR_Darwin64_SaveList :
111111 CSR_Darwin32_SaveList;
112
113 // For 32-bit SVR4, also initialize the frame index associated with
114 // the CR spill slot.
115 if (!Subtarget.isPPC64())
116 CRSpillFrameIdx = 0;
112117
113118 return Subtarget.isPPC64() ? CSR_SVR464_SaveList : CSR_SVR432_SaveList;
114119 }
476481 MBB.erase(II);
477482 }
478483
484 bool
485 PPCRegisterInfo::hasReservedSpillSlot(const MachineFunction &MF,
486 unsigned Reg, int &FrameIdx) const {
487
488 // For the nonvolatile condition registers (CR2, CR3, CR4) in an SVR4
489 // ABI, return true to prevent allocating an additional frame slot.
490 // For 64-bit, the CR save area is at SP+8; the value of FrameIdx = 0
491 // is arbitrary and will be subsequently ignored. For 32-bit, we must
492 // create exactly one stack slot and return its FrameIdx for all
493 // nonvolatiles.
494 if (Subtarget.isSVR4ABI() && PPC::CR2 <= Reg && Reg <= PPC::CR4) {
495 if (Subtarget.isPPC64()) {
496 FrameIdx = 0;
497 } else if (CRSpillFrameIdx) {
498 FrameIdx = CRSpillFrameIdx;
499 } else {
500 MachineFrameInfo *MFI = ((MachineFunction &)MF).getFrameInfo();
501 FrameIdx = MFI->CreateFixedObject((uint64_t)4, (int64_t)-4, true);
502 CRSpillFrameIdx = FrameIdx;
503 }
504 return true;
505 }
506 return false;
507 }
508
479509 void
480510 PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
481511 int SPAdj, RegScavenger *RS) const {
2929 std::map ImmToIdxMap;
3030 const PPCSubtarget &Subtarget;
3131 const TargetInstrInfo &TII;
32 mutable int CRSpillFrameIdx;
3233 public:
3334 PPCRegisterInfo(const PPCSubtarget &SubTarget, const TargetInstrInfo &tii);
3435
6465 int SPAdj, RegScavenger *RS) const;
6566 void lowerCRRestore(MachineBasicBlock::iterator II, unsigned FrameIndex,
6667 int SPAdj, RegScavenger *RS) const;
68 bool hasReservedSpillSlot(const MachineFunction &MF, unsigned Reg,
69 int &FrameIdx) const;
6770 void eliminateFrameIndex(MachineBasicBlock::iterator II,
6871 int SPAdj, RegScavenger *RS = NULL) const;
6972
0 ; RUN: llc -O0 -disable-fp-elim -mtriple=powerpc-unknown-linux-gnu < %s | FileCheck %s -check-prefix=PPC32
1 ; RUN: llc -O0 -disable-fp-elim -mtriple=powerpc64-unknown-linux-gnu < %s | FileCheck %s -check-prefix=PPC64
2
3 declare void @foo()
4
5 define i32 @test_cr2() nounwind {
6 entry:
7 %ret = alloca i32, align 4
8 %0 = call i32 asm sideeffect "\0A\09mtcr $4\0A\09cmp 2,$2,$1\0A\09mfcr $0", "=r,r,r,r,r,~{cr2}"(i32 1, i32 2, i32 3, i32 0) nounwind
9 store i32 %0, i32* %ret, align 4
10 call void @foo()
11 %1 = load i32* %ret, align 4
12 ret i32 %1
13 }
14
15 ; PPC32: mfcr 12
16 ; PPC32-NEXT: stw 12, {{[0-9]+}}(31)
17 ; PPC32: lwz 12, {{[0-9]+}}(31)
18 ; PPC32-NEXT: mtcrf 32, 12
19
20 ; PPC64: mfcr 12
21 ; PPC64-NEXT: stw 12, 8(1)
22 ; PPC64: lwz 12, 8(1)
23 ; PPC64-NEXT: mtcrf 32, 12
24
25 define i32 @test_cr234() nounwind {
26 entry:
27 %ret = alloca i32, align 4
28 %0 = call i32 asm sideeffect "\0A\09mtcr $4\0A\09cmp 2,$2,$1\0A\09cmp 3,$2,$2\0A\09cmp 4,$2,$3\0A\09mfcr $0", "=r,r,r,r,r,~{cr2},~{cr3},~{cr4}"(i32 1, i32 2, i32 3, i32 0) nounwind
29 store i32 %0, i32* %ret, align 4
30 call void @foo()
31 %1 = load i32* %ret, align 4
32 ret i32 %1
33 }
34
35 ; PPC32: mfcr 12
36 ; PPC32-NEXT: stw 12, {{[0-9]+}}(31)
37 ; PPC32: lwz 12, {{[0-9]+}}(31)
38 ; PPC32-NEXT: mtcrf 32, 12
39 ; PPC32-NEXT: mtcrf 16, 12
40 ; PPC32-NEXT: mtcrf 8, 12
41
42 ; PPC64: mfcr 12
43 ; PPC64-NEXT: stw 12, 8(1)
44 ; PPC64: lwz 12, 8(1)
45 ; PPC64-NEXT: mtcrf 32, 12
46 ; PPC64-NEXT: mtcrf 16, 12
47 ; PPC64-NEXT: mtcrf 8, 12
48