blob: c3007c4aec08720113f166bf6694a4289461d475 [file] [log] [blame]
Nate Begeman21e463b2005-10-16 05:39:50 +00001//===- PPCRegisterInfo.cpp - PowerPC Register Information -------*- C++ -*-===//
Misha Brukmanb5f662f2005-04-21 23:30:14 +00002//
Misha Brukmanf2ccb772004-08-17 04:55:41 +00003// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
Misha Brukmanb5f662f2005-04-21 23:30:14 +00007//
Misha Brukmanf2ccb772004-08-17 04:55:41 +00008//===----------------------------------------------------------------------===//
9//
Nate Begeman21e463b2005-10-16 05:39:50 +000010// This file contains the PowerPC implementation of the MRegisterInfo class.
Misha Brukmanf2ccb772004-08-17 04:55:41 +000011//
12//===----------------------------------------------------------------------===//
13
14#define DEBUG_TYPE "reginfo"
Chris Lattner26689592005-10-14 23:51:18 +000015#include "PPC.h"
Chris Lattner26bd0d42005-10-14 23:45:43 +000016#include "PPCInstrBuilder.h"
Chris Lattner16e71f22005-10-14 23:59:06 +000017#include "PPCRegisterInfo.h"
Misha Brukmanf2ccb772004-08-17 04:55:41 +000018#include "llvm/Constants.h"
19#include "llvm/Type.h"
20#include "llvm/CodeGen/ValueTypes.h"
21#include "llvm/CodeGen/MachineInstrBuilder.h"
22#include "llvm/CodeGen/MachineFunction.h"
23#include "llvm/CodeGen/MachineFrameInfo.h"
Jim Laskeyf1d78e82006-03-23 18:12:57 +000024#include "llvm/CodeGen/MachineLocation.h"
Misha Brukmanf2ccb772004-08-17 04:55:41 +000025#include "llvm/Target/TargetFrameInfo.h"
26#include "llvm/Target/TargetMachine.h"
27#include "llvm/Target/TargetOptions.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000028#include "llvm/Support/CommandLine.h"
29#include "llvm/Support/Debug.h"
Nate Begemanae232e72005-11-06 09:00:38 +000030#include "llvm/Support/MathExtras.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000031#include "llvm/ADT/STLExtras.h"
Misha Brukmanf2ccb772004-08-17 04:55:41 +000032#include <cstdlib>
33#include <iostream>
34using namespace llvm;
35
Nate Begeman21e463b2005-10-16 05:39:50 +000036PPCRegisterInfo::PPCRegisterInfo()
Chris Lattner4c7b43b2005-10-14 23:37:35 +000037 : PPCGenRegisterInfo(PPC::ADJCALLSTACKDOWN, PPC::ADJCALLSTACKUP) {
Misha Brukmanb5f662f2005-04-21 23:30:14 +000038 ImmToIdxMap[PPC::LD] = PPC::LDX; ImmToIdxMap[PPC::STD] = PPC::STDX;
Misha Brukmanf2ccb772004-08-17 04:55:41 +000039 ImmToIdxMap[PPC::LBZ] = PPC::LBZX; ImmToIdxMap[PPC::STB] = PPC::STBX;
40 ImmToIdxMap[PPC::LHZ] = PPC::LHZX; ImmToIdxMap[PPC::LHA] = PPC::LHAX;
41 ImmToIdxMap[PPC::LWZ] = PPC::LWZX; ImmToIdxMap[PPC::LWA] = PPC::LWAX;
42 ImmToIdxMap[PPC::LFS] = PPC::LFSX; ImmToIdxMap[PPC::LFD] = PPC::LFDX;
43 ImmToIdxMap[PPC::STH] = PPC::STHX; ImmToIdxMap[PPC::STW] = PPC::STWX;
44 ImmToIdxMap[PPC::STFS] = PPC::STFSX; ImmToIdxMap[PPC::STFD] = PPC::STFDX;
Nate Begeman1d9d7422005-10-18 00:28:58 +000045 ImmToIdxMap[PPC::ADDI] = PPC::ADD4;
Misha Brukmanf2ccb772004-08-17 04:55:41 +000046}
47
Misha Brukmanb5f662f2005-04-21 23:30:14 +000048void
Nate Begeman21e463b2005-10-16 05:39:50 +000049PPCRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
50 MachineBasicBlock::iterator MI,
51 unsigned SrcReg, int FrameIdx,
52 const TargetRegisterClass *RC) const {
Misha Brukmanf2ccb772004-08-17 04:55:41 +000053 if (SrcReg == PPC::LR) {
Chris Lattner9c09c9e2006-03-16 22:24:02 +000054 // FIXME: this spills LR immediately to memory in one step. To do this, we
55 // use R11, which we know cannot be used in the prolog/epilog. This is a
56 // hack.
Chris Lattner3f852b42005-08-18 23:24:50 +000057 BuildMI(MBB, MI, PPC::MFLR, 1, PPC::R11);
Chris Lattner919c0322005-10-01 01:35:02 +000058 addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(PPC::R11), FrameIdx);
Nate Begeman1d9d7422005-10-18 00:28:58 +000059 } else if (RC == PPC::CRRCRegisterClass) {
Nate Begeman7af02482005-04-12 07:04:16 +000060 BuildMI(MBB, MI, PPC::MFCR, 0, PPC::R11);
Chris Lattner919c0322005-10-01 01:35:02 +000061 addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(PPC::R11), FrameIdx);
Nate Begeman1d9d7422005-10-18 00:28:58 +000062 } else if (RC == PPC::GPRCRegisterClass) {
Chris Lattner919c0322005-10-01 01:35:02 +000063 addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(SrcReg),FrameIdx);
Nate Begeman1d9d7422005-10-18 00:28:58 +000064 } else if (RC == PPC::G8RCRegisterClass) {
65 addFrameReference(BuildMI(MBB, MI, PPC::STD, 3).addReg(SrcReg),FrameIdx);
66 } else if (RC == PPC::F8RCRegisterClass) {
Chris Lattner919c0322005-10-01 01:35:02 +000067 addFrameReference(BuildMI(MBB, MI, PPC::STFD, 3).addReg(SrcReg),FrameIdx);
Nate Begeman1d9d7422005-10-18 00:28:58 +000068 } else if (RC == PPC::F4RCRegisterClass) {
Chris Lattner919c0322005-10-01 01:35:02 +000069 addFrameReference(BuildMI(MBB, MI, PPC::STFS, 3).addReg(SrcReg),FrameIdx);
Chris Lattner9c09c9e2006-03-16 22:24:02 +000070 } else if (RC == PPC::VRRCRegisterClass) {
71 // We don't have indexed addressing for vector loads. Emit:
72 // R11 = ADDI FI#
73 // Dest = LVX R0, R11
74 //
75 // FIXME: We use R0 here, because it isn't available for RA.
76 addFrameReference(BuildMI(MBB, MI, PPC::ADDI, 1, PPC::R0), FrameIdx, 0, 0);
77 BuildMI(MBB, MI, PPC::STVX, 3)
78 .addReg(SrcReg).addReg(PPC::R0).addReg(PPC::R0);
Misha Brukmanf2ccb772004-08-17 04:55:41 +000079 } else {
Chris Lattner919c0322005-10-01 01:35:02 +000080 assert(0 && "Unknown regclass!");
81 abort();
Misha Brukmanf2ccb772004-08-17 04:55:41 +000082 }
83}
84
85void
Nate Begeman21e463b2005-10-16 05:39:50 +000086PPCRegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
Misha Brukmanf2ccb772004-08-17 04:55:41 +000087 MachineBasicBlock::iterator MI,
Chris Lattnerb48d2cf2005-09-30 01:31:52 +000088 unsigned DestReg, int FrameIdx,
89 const TargetRegisterClass *RC) const {
Misha Brukmanf2ccb772004-08-17 04:55:41 +000090 if (DestReg == PPC::LR) {
Chris Lattner919c0322005-10-01 01:35:02 +000091 addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, PPC::R11), FrameIdx);
Misha Brukmanf2ccb772004-08-17 04:55:41 +000092 BuildMI(MBB, MI, PPC::MTLR, 1).addReg(PPC::R11);
Nate Begeman1d9d7422005-10-18 00:28:58 +000093 } else if (RC == PPC::CRRCRegisterClass) {
Chris Lattner919c0322005-10-01 01:35:02 +000094 addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, PPC::R11), FrameIdx);
Nate Begeman7af02482005-04-12 07:04:16 +000095 BuildMI(MBB, MI, PPC::MTCRF, 1, DestReg).addReg(PPC::R11);
Nate Begeman1d9d7422005-10-18 00:28:58 +000096 } else if (RC == PPC::GPRCRegisterClass) {
Chris Lattner919c0322005-10-01 01:35:02 +000097 addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, DestReg), FrameIdx);
Nate Begeman1d9d7422005-10-18 00:28:58 +000098 } else if (RC == PPC::G8RCRegisterClass) {
99 addFrameReference(BuildMI(MBB, MI, PPC::LD, 2, DestReg), FrameIdx);
100 } else if (RC == PPC::F8RCRegisterClass) {
Chris Lattner919c0322005-10-01 01:35:02 +0000101 addFrameReference(BuildMI(MBB, MI, PPC::LFD, 2, DestReg), FrameIdx);
Nate Begeman1d9d7422005-10-18 00:28:58 +0000102 } else if (RC == PPC::F4RCRegisterClass) {
Chris Lattner919c0322005-10-01 01:35:02 +0000103 addFrameReference(BuildMI(MBB, MI, PPC::LFS, 2, DestReg), FrameIdx);
Chris Lattner9c09c9e2006-03-16 22:24:02 +0000104 } else if (RC == PPC::VRRCRegisterClass) {
105 // We don't have indexed addressing for vector loads. Emit:
106 // R11 = ADDI FI#
107 // Dest = LVX R0, R11
108 //
109 // FIXME: We use R0 here, because it isn't available for RA.
110 addFrameReference(BuildMI(MBB, MI, PPC::ADDI, 1, PPC::R0), FrameIdx, 0, 0);
111 BuildMI(MBB, MI, PPC::LVX, 2, DestReg).addReg(PPC::R0).addReg(PPC::R0);
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000112 } else {
Chris Lattner919c0322005-10-01 01:35:02 +0000113 assert(0 && "Unknown regclass!");
114 abort();
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000115 }
116}
117
Nate Begeman21e463b2005-10-16 05:39:50 +0000118void PPCRegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
119 MachineBasicBlock::iterator MI,
120 unsigned DestReg, unsigned SrcReg,
121 const TargetRegisterClass *RC) const {
Nate Begeman1d9d7422005-10-18 00:28:58 +0000122 if (RC == PPC::GPRCRegisterClass) {
123 BuildMI(MBB, MI, PPC::OR4, 2, DestReg).addReg(SrcReg).addReg(SrcReg);
124 } else if (RC == PPC::G8RCRegisterClass) {
125 BuildMI(MBB, MI, PPC::OR8, 2, DestReg).addReg(SrcReg).addReg(SrcReg);
126 } else if (RC == PPC::F4RCRegisterClass) {
Chris Lattner919c0322005-10-01 01:35:02 +0000127 BuildMI(MBB, MI, PPC::FMRS, 1, DestReg).addReg(SrcReg);
Nate Begeman1d9d7422005-10-18 00:28:58 +0000128 } else if (RC == PPC::F8RCRegisterClass) {
Chris Lattner919c0322005-10-01 01:35:02 +0000129 BuildMI(MBB, MI, PPC::FMRD, 1, DestReg).addReg(SrcReg);
Nate Begeman1d9d7422005-10-18 00:28:58 +0000130 } else if (RC == PPC::CRRCRegisterClass) {
Nate Begeman7af02482005-04-12 07:04:16 +0000131 BuildMI(MBB, MI, PPC::MCRF, 1, DestReg).addReg(SrcReg);
Chris Lattner335fd3c2006-03-16 20:03:58 +0000132 } else if (RC == PPC::VRRCRegisterClass) {
133 BuildMI(MBB, MI, PPC::VOR, 2, DestReg).addReg(SrcReg).addReg(SrcReg);
Nate Begeman7af02482005-04-12 07:04:16 +0000134 } else {
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000135 std::cerr << "Attempt to copy register that is not GPR or FPR";
136 abort();
137 }
138}
139
Chris Lattnerf38df042005-09-09 21:46:49 +0000140/// foldMemoryOperand - PowerPC (like most RISC's) can only fold spills into
141/// copy instructions, turning them into load/store instructions.
Nate Begeman21e463b2005-10-16 05:39:50 +0000142MachineInstr *PPCRegisterInfo::foldMemoryOperand(MachineInstr *MI,
143 unsigned OpNum,
144 int FrameIndex) const {
Chris Lattnerf38df042005-09-09 21:46:49 +0000145 // Make sure this is a reg-reg copy. Note that we can't handle MCRF, because
146 // it takes more than one instruction to store it.
147 unsigned Opc = MI->getOpcode();
148
Nate Begeman1d9d7422005-10-18 00:28:58 +0000149 if ((Opc == PPC::OR4 &&
Chris Lattnerf38df042005-09-09 21:46:49 +0000150 MI->getOperand(1).getReg() == MI->getOperand(2).getReg())) {
151 if (OpNum == 0) { // move -> store
152 unsigned InReg = MI->getOperand(1).getReg();
153 return addFrameReference(BuildMI(PPC::STW,
154 3).addReg(InReg), FrameIndex);
Chris Lattnerc9fe7502005-09-09 21:59:44 +0000155 } else { // move -> load
Chris Lattnerf38df042005-09-09 21:46:49 +0000156 unsigned OutReg = MI->getOperand(0).getReg();
157 return addFrameReference(BuildMI(PPC::LWZ, 2, OutReg), FrameIndex);
158 }
Nate Begeman1d9d7422005-10-18 00:28:58 +0000159 } else if ((Opc == PPC::OR8 &&
160 MI->getOperand(1).getReg() == MI->getOperand(2).getReg())) {
161 if (OpNum == 0) { // move -> store
162 unsigned InReg = MI->getOperand(1).getReg();
163 return addFrameReference(BuildMI(PPC::STD,
164 3).addReg(InReg), FrameIndex);
165 } else { // move -> load
166 unsigned OutReg = MI->getOperand(0).getReg();
167 return addFrameReference(BuildMI(PPC::LD, 2, OutReg), FrameIndex);
168 }
Chris Lattner919c0322005-10-01 01:35:02 +0000169 } else if (Opc == PPC::FMRD) {
Chris Lattnerc9fe7502005-09-09 21:59:44 +0000170 if (OpNum == 0) { // move -> store
171 unsigned InReg = MI->getOperand(1).getReg();
172 return addFrameReference(BuildMI(PPC::STFD,
173 3).addReg(InReg), FrameIndex);
174 } else { // move -> load
175 unsigned OutReg = MI->getOperand(0).getReg();
176 return addFrameReference(BuildMI(PPC::LFD, 2, OutReg), FrameIndex);
177 }
Chris Lattner919c0322005-10-01 01:35:02 +0000178 } else if (Opc == PPC::FMRS) {
179 if (OpNum == 0) { // move -> store
180 unsigned InReg = MI->getOperand(1).getReg();
181 return addFrameReference(BuildMI(PPC::STFS,
182 3).addReg(InReg), FrameIndex);
183 } else { // move -> load
184 unsigned OutReg = MI->getOperand(0).getReg();
185 return addFrameReference(BuildMI(PPC::LFS, 2, OutReg), FrameIndex);
186 }
Chris Lattnerf38df042005-09-09 21:46:49 +0000187 }
188 return 0;
189}
190
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000191//===----------------------------------------------------------------------===//
192// Stack Frame Processing methods
193//===----------------------------------------------------------------------===//
194
195// hasFP - Return true if the specified function should have a dedicated frame
196// pointer register. This is true if the function has variable sized allocas or
197// if frame pointer elimination is disabled.
198//
Chris Lattner4f91a4c2006-04-03 22:03:29 +0000199static bool hasFP(const MachineFunction &MF) {
200 const MachineFrameInfo *MFI = MF.getFrameInfo();
201 unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
202
203 // If frame pointers are forced, if there are variable sized stack objects,
204 // or if there is an object on the stack that requires more alignment than is
205 // normally provided, use a frame pointer.
206 //
207 return NoFramePointerElim || MFI->hasVarSizedObjects() ||
208 MFI->getMaxAlignment() > TargetAlign;
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000209}
210
Nate Begeman21e463b2005-10-16 05:39:50 +0000211void PPCRegisterInfo::
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000212eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
213 MachineBasicBlock::iterator I) const {
214 if (hasFP(MF)) {
215 // If we have a frame pointer, convert as follows:
216 // ADJCALLSTACKDOWN -> addi, r1, r1, -amount
217 // ADJCALLSTACKUP -> addi, r1, r1, amount
218 MachineInstr *Old = I;
219 unsigned Amount = Old->getOperand(0).getImmedValue();
220 if (Amount != 0) {
221 // We need to keep the stack aligned properly. To do this, we round the
222 // amount of space needed for the outgoing arguments up to the next
223 // alignment boundary.
224 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
225 Amount = (Amount+Align-1)/Align*Align;
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000226
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000227 // Replace the pseudo instruction with a new instruction...
228 if (Old->getOpcode() == PPC::ADJCALLSTACKDOWN) {
Chris Lattnerc6d48d32006-01-11 23:07:57 +0000229 BuildMI(MBB, I, PPC::ADDI, 2, PPC::R1).addReg(PPC::R1).addSImm(-Amount);
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000230 } else {
231 assert(Old->getOpcode() == PPC::ADJCALLSTACKUP);
Chris Lattnerc6d48d32006-01-11 23:07:57 +0000232 BuildMI(MBB, I, PPC::ADDI, 2, PPC::R1).addReg(PPC::R1).addSImm(Amount);
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000233 }
234 }
235 }
236 MBB.erase(I);
237}
238
239void
Nate Begeman21e463b2005-10-16 05:39:50 +0000240PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000241 unsigned i = 0;
242 MachineInstr &MI = *II;
243 MachineBasicBlock &MBB = *MI.getParent();
244 MachineFunction &MF = *MBB.getParent();
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000245
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000246 while (!MI.getOperand(i).isFrameIndex()) {
247 ++i;
248 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
249 }
250
251 int FrameIndex = MI.getOperand(i).getFrameIndex();
252
253 // Replace the FrameIndex with base register with GPR1 (SP) or GPR31 (FP).
254 MI.SetMachineOperandReg(i, hasFP(MF) ? PPC::R31 : PPC::R1);
255
256 // Take into account whether it's an add or mem instruction
257 unsigned OffIdx = (i == 2) ? 1 : 2;
258
259 // Now add the frame object offset to the offset from r1.
260 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
261 MI.getOperand(OffIdx).getImmedValue();
262
263 // If we're not using a Frame Pointer that has been set to the value of the
264 // SP before having the stack size subtracted from it, then add the stack size
265 // to Offset to get the correct offset.
266 Offset += MF.getFrameInfo()->getStackSize();
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000267
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000268 if (Offset > 32767 || Offset < -32768) {
269 // Insert a set of r0 with the full offset value before the ld, st, or add
270 MachineBasicBlock *MBB = MI.getParent();
Chris Lattnerc6d48d32006-01-11 23:07:57 +0000271 BuildMI(*MBB, II, PPC::LIS, 1, PPC::R0).addSImm(Offset >> 16);
272 BuildMI(*MBB, II, PPC::ORI, 2, PPC::R0).addReg(PPC::R0).addImm(Offset);
273
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000274 // convert into indexed form of the instruction
275 // sth 0:rA, 1:imm 2:(rB) ==> sthx 0:rA, 2:rB, 1:r0
276 // addi 0:rA 1:rB, 2, imm ==> add 0:rA, 1:rB, 2:r0
Chris Lattner14630192005-09-09 20:51:08 +0000277 assert(ImmToIdxMap.count(MI.getOpcode()) &&
278 "No indexed form of load or store available!");
279 unsigned NewOpcode = ImmToIdxMap.find(MI.getOpcode())->second;
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000280 MI.setOpcode(NewOpcode);
281 MI.SetMachineOperandReg(1, MI.getOperand(i).getReg());
282 MI.SetMachineOperandReg(2, PPC::R0);
283 } else {
Chris Lattner841d12d2005-10-18 16:51:22 +0000284 switch (MI.getOpcode()) {
285 case PPC::LWA:
286 case PPC::LD:
287 case PPC::STD:
Chris Lattnerecfe55e2006-03-22 05:30:33 +0000288 case PPC::STD_32:
Chris Lattner841d12d2005-10-18 16:51:22 +0000289 assert((Offset & 3) == 0 && "Invalid frame offset!");
290 Offset >>= 2; // The actual encoded value has the low two bits zero.
291 break;
292 }
Chris Lattner919c0322005-10-01 01:35:02 +0000293 MI.SetMachineOperandConst(OffIdx, MachineOperand::MO_SignExtendedImmed,
294 Offset);
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000295 }
296}
297
Chris Lattner1877ec92006-03-13 21:52:10 +0000298// HandleVRSaveUpdate - MI is the UPDATE_VRSAVE instruction introduced by the
299// instruction selector. Based on the vector registers that have been used,
300// transform this into the appropriate ORI instruction.
301static void HandleVRSaveUpdate(MachineInstr *MI, const bool *UsedRegs) {
302 unsigned UsedRegMask = 0;
303#define HANDLEREG(N) if (UsedRegs[PPC::V##N]) UsedRegMask |= 1 << (31-N)
304 HANDLEREG( 0); HANDLEREG( 1); HANDLEREG( 2); HANDLEREG( 3);
305 HANDLEREG( 4); HANDLEREG( 5); HANDLEREG( 6); HANDLEREG( 7);
306 HANDLEREG( 8); HANDLEREG( 9); HANDLEREG(10); HANDLEREG(11);
307 HANDLEREG(12); HANDLEREG(13); HANDLEREG(14); HANDLEREG(15);
308 HANDLEREG(16); HANDLEREG(17); HANDLEREG(18); HANDLEREG(19);
309 HANDLEREG(20); HANDLEREG(21); HANDLEREG(22); HANDLEREG(23);
310 HANDLEREG(24); HANDLEREG(25); HANDLEREG(26); HANDLEREG(27);
311 HANDLEREG(28); HANDLEREG(29); HANDLEREG(30); HANDLEREG(31);
312#undef HANDLEREG
313 unsigned SrcReg = MI->getOperand(1).getReg();
314 unsigned DstReg = MI->getOperand(0).getReg();
315 // If no registers are used, turn this into a copy.
316 if (UsedRegMask == 0) {
317 if (SrcReg != DstReg)
318 BuildMI(*MI->getParent(), MI, PPC::OR4, 2, DstReg)
319 .addReg(SrcReg).addReg(SrcReg);
320 } else if ((UsedRegMask & 0xFFFF) == UsedRegMask) {
321 BuildMI(*MI->getParent(), MI, PPC::ORI, 2, DstReg)
322 .addReg(SrcReg).addImm(UsedRegMask);
323 } else if ((UsedRegMask & 0xFFFF0000) == UsedRegMask) {
324 BuildMI(*MI->getParent(), MI, PPC::ORIS, 2, DstReg)
325 .addReg(SrcReg).addImm(UsedRegMask >> 16);
326 } else {
327 BuildMI(*MI->getParent(), MI, PPC::ORIS, 2, DstReg)
328 .addReg(SrcReg).addImm(UsedRegMask >> 16);
329 BuildMI(*MI->getParent(), MI, PPC::ORI, 2, DstReg)
330 .addReg(DstReg).addImm(UsedRegMask & 0xFFFF);
331 }
332
333 // Remove the old UPDATE_VRSAVE instruction.
334 MI->getParent()->erase(MI);
335}
336
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000337
Nate Begeman21e463b2005-10-16 05:39:50 +0000338void PPCRegisterInfo::emitPrologue(MachineFunction &MF) const {
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000339 MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
340 MachineBasicBlock::iterator MBBI = MBB.begin();
341 MachineFrameInfo *MFI = MF.getFrameInfo();
Chris Lattner4f91a4c2006-04-03 22:03:29 +0000342
343 // Do we have a frame pointer for this function?
344 bool HasFP = hasFP(MF);
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000345
Chris Lattner4f91a4c2006-04-03 22:03:29 +0000346 // Scan the prolog, looking for an UPDATE_VRSAVE instruction. If we find it,
347 // process it.
Chris Lattner8aa777d2006-03-16 21:31:45 +0000348 for (unsigned i = 0; MBBI != MBB.end(); ++i, ++MBBI) {
Chris Lattner1877ec92006-03-13 21:52:10 +0000349 if (MBBI->getOpcode() == PPC::UPDATE_VRSAVE) {
350 HandleVRSaveUpdate(MBBI, MF.getUsedPhysregs());
351 break;
352 }
353 }
354
355 // Move MBBI back to the beginning of the function.
356 MBBI = MBB.begin();
357
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000358 // Get the number of bytes to allocate from the FrameInfo
359 unsigned NumBytes = MFI->getStackSize();
Nate Begemanae232e72005-11-06 09:00:38 +0000360
361 // Get the alignments provided by the target, and the maximum alignment
362 // (if any) of the fixed frame objects.
363 unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
364 unsigned MaxAlign = MFI->getMaxAlignment();
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000365
366 // If we have calls, we cannot use the red zone to store callee save registers
367 // and we must set up a stack frame, so calculate the necessary size here.
368 if (MFI->hasCalls()) {
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000369 // We reserve argument space for call sites in the function immediately on
370 // entry to the current function. This eliminates the need for add/sub
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000371 // brackets around call sites.
372 NumBytes += MFI->getMaxCallFrameSize();
373 }
374
Jeff Cohend29b6aa2005-07-30 18:33:25 +0000375 // If we are a leaf function, and use up to 224 bytes of stack space,
Nate Begeman54eed362005-07-27 06:06:29 +0000376 // and don't have a frame pointer, then we do not need to adjust the stack
377 // pointer (we fit in the Red Zone).
Chris Lattner4f91a4c2006-04-03 22:03:29 +0000378 if ((NumBytes == 0) || (NumBytes <= 224 && !HasFP && !MFI->hasCalls() &&
Nate Begemanae232e72005-11-06 09:00:38 +0000379 MaxAlign <= TargetAlign)) {
Nate Begeman54eed362005-07-27 06:06:29 +0000380 MFI->setStackSize(0);
381 return;
382 }
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000383
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000384 // Add the size of R1 to NumBytes size for the store of R1 to the bottom
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000385 // of the stack and round the size to a multiple of the alignment.
Nate Begemanae232e72005-11-06 09:00:38 +0000386 unsigned Align = std::max(TargetAlign, MaxAlign);
Chris Lattner5802be12005-09-30 17:16:59 +0000387 unsigned GPRSize = 4;
Chris Lattner4f91a4c2006-04-03 22:03:29 +0000388 unsigned Size = HasFP ? GPRSize + GPRSize : GPRSize;
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000389 NumBytes = (NumBytes+Size+Align-1)/Align*Align;
390
391 // Update frame info to pretend that this is part of the stack...
392 MFI->setStackSize(NumBytes);
393
Nate Begeman3dee1752005-07-27 23:11:27 +0000394 // Adjust stack pointer: r1 -= numbytes.
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000395 if (NumBytes <= 32768) {
Chris Lattnerc6d48d32006-01-11 23:07:57 +0000396 BuildMI(MBB, MBBI, PPC::STWU, 3)
397 .addReg(PPC::R1).addSImm(-NumBytes).addReg(PPC::R1);
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000398 } else {
399 int NegNumbytes = -NumBytes;
Chris Lattnerc6d48d32006-01-11 23:07:57 +0000400 BuildMI(MBB, MBBI, PPC::LIS, 1, PPC::R0).addSImm(NegNumbytes >> 16);
401 BuildMI(MBB, MBBI, PPC::ORI, 2, PPC::R0)
402 .addReg(PPC::R0).addImm(NegNumbytes & 0xFFFF);
403 BuildMI(MBB, MBBI, PPC::STWUX, 3)
404 .addReg(PPC::R1).addReg(PPC::R1).addReg(PPC::R0);
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000405 }
Nate Begemanae232e72005-11-06 09:00:38 +0000406
407 // If there is a preferred stack alignment, align R1 now
408 // FIXME: If this ever matters, this could be made more efficient by folding
409 // this into the code above, so that we don't issue two store+update
410 // instructions.
411 if (MaxAlign > TargetAlign) {
412 assert(isPowerOf2_32(MaxAlign) && MaxAlign < 32767 && "Invalid alignment!");
Chris Lattnerc6d48d32006-01-11 23:07:57 +0000413 BuildMI(MBB, MBBI, PPC::RLWINM, 4, PPC::R0)
414 .addReg(PPC::R1).addImm(0).addImm(32-Log2_32(MaxAlign)).addImm(31);
415 BuildMI(MBB, MBBI, PPC::SUBFIC, 2,PPC::R0).addReg(PPC::R0).addImm(MaxAlign);
416 BuildMI(MBB, MBBI, PPC::STWUX, 3)
417 .addReg(PPC::R1).addReg(PPC::R1).addReg(PPC::R0);
Nate Begemanae232e72005-11-06 09:00:38 +0000418 }
419
420 // If there is a frame pointer, copy R1 (SP) into R31 (FP)
Chris Lattner4f91a4c2006-04-03 22:03:29 +0000421 if (HasFP) {
Chris Lattnerc6d48d32006-01-11 23:07:57 +0000422 BuildMI(MBB, MBBI, PPC::STW, 3)
423 .addReg(PPC::R31).addSImm(GPRSize).addReg(PPC::R1);
424 BuildMI(MBB, MBBI, PPC::OR4, 2, PPC::R31).addReg(PPC::R1).addReg(PPC::R1);
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000425 }
426}
427
Nate Begeman21e463b2005-10-16 05:39:50 +0000428void PPCRegisterInfo::emitEpilogue(MachineFunction &MF,
429 MachineBasicBlock &MBB) const {
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000430 MachineBasicBlock::iterator MBBI = prior(MBB.end());
Evan Cheng6da8d992006-01-09 18:28:21 +0000431 assert(MBBI->getOpcode() == PPC::BLR &&
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000432 "Can only insert epilog into returning blocks");
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000433
Chris Lattner64da1722006-01-11 23:03:54 +0000434 // Get the number of bytes allocated from the FrameInfo.
435 unsigned NumBytes = MF.getFrameInfo()->getStackSize();
436 unsigned GPRSize = 4;
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000437
438 if (NumBytes != 0) {
Chris Lattner64da1722006-01-11 23:03:54 +0000439 // If this function has a frame pointer, load the saved stack pointer from
440 // its stack slot.
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000441 if (hasFP(MF)) {
Chris Lattner64da1722006-01-11 23:03:54 +0000442 BuildMI(MBB, MBBI, PPC::LWZ, 2, PPC::R31)
443 .addSImm(GPRSize).addReg(PPC::R31);
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000444 }
Chris Lattner64da1722006-01-11 23:03:54 +0000445
446 // The loaded (or persistent) stack pointer value is offseted by the 'stwu'
447 // on entry to the function. Add this offset back now.
Chris Lattnerba625722006-01-11 23:16:29 +0000448 if (NumBytes < 32768) {
Chris Lattner64da1722006-01-11 23:03:54 +0000449 BuildMI(MBB, MBBI, PPC::ADDI, 2, PPC::R1)
450 .addReg(PPC::R1).addSImm(NumBytes);
451 } else {
452 BuildMI(MBB, MBBI, PPC::LIS, 1, PPC::R0).addSImm(NumBytes >> 16);
453 BuildMI(MBB, MBBI, PPC::ORI, 2, PPC::R0)
454 .addReg(PPC::R0).addImm(NumBytes & 0xFFFF);
455 BuildMI(MBB, MBBI, PPC::ADD4, 2, PPC::R1)
456 .addReg(PPC::R0).addReg(PPC::R1);
457 }
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000458 }
459}
460
Jim Laskeya9979182006-03-28 13:48:33 +0000461unsigned PPCRegisterInfo::getFrameRegister(MachineFunction &MF) const {
462 return getDwarfRegNum(hasFP(MF) ? PPC::R31 : PPC::R1);
Jim Laskeyf1d78e82006-03-23 18:12:57 +0000463}
464
Chris Lattner4c7b43b2005-10-14 23:37:35 +0000465#include "PPCGenRegisterInfo.inc"
Misha Brukmanf2ccb772004-08-17 04:55:41 +0000466