PPCRegisterInfo.cpp revision dc77540d9506dc151d79b94bae88bd841880ef37
121e463b2bf864671a87ebe386cb100ef9349a540Nate Begeman//===- PPCRegisterInfo.cpp - PowerPC Register Information -------*- C++ -*-===//
2b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman//
3f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman//                     The LLVM Compiler Infrastructure
4f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman//
5f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman// This file was developed by the LLVM research group and is distributed under
6f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman// the University of Illinois Open Source License. See LICENSE.TXT for details.
7b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman//
8f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman//===----------------------------------------------------------------------===//
9f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman//
1021e463b2bf864671a87ebe386cb100ef9349a540Nate Begeman// This file contains the PowerPC implementation of the MRegisterInfo class.
11f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman//
12f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman//===----------------------------------------------------------------------===//
13f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman
14f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman#define DEBUG_TYPE "reginfo"
152668959b8879097db368aec7d76c455260abc75bChris Lattner#include "PPC.h"
1626bd0d48a164c419462133270e3ec1c2401a34d7Chris Lattner#include "PPCInstrBuilder.h"
172f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey#include "PPCMachineFunctionInfo.h"
1816e71f2f70811c69c56052dd146324fe20e31db5Chris Lattner#include "PPCRegisterInfo.h"
192f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey#include "PPCFrameInfo.h"
20804e06704261f233111913a047ef7f7dec1b8725Chris Lattner#include "PPCSubtarget.h"
21f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman#include "llvm/Constants.h"
22f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman#include "llvm/Type.h"
23f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman#include "llvm/CodeGen/ValueTypes.h"
24f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman#include "llvm/CodeGen/MachineInstrBuilder.h"
254188699f80c233a20b6ddc61570a8a8c1804cb85Jim Laskey#include "llvm/CodeGen/MachineDebugInfo.h"
26f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman#include "llvm/CodeGen/MachineFunction.h"
27f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman#include "llvm/CodeGen/MachineFrameInfo.h"
28f1d78e83356a412e525c30ac90dabf090a8cfc99Jim Laskey#include "llvm/CodeGen/MachineLocation.h"
294188699f80c233a20b6ddc61570a8a8c1804cb85Jim Laskey#include "llvm/CodeGen/SelectionDAGNodes.h"
30f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman#include "llvm/Target/TargetFrameInfo.h"
31f9568d8700d5389799796262cde313bb5c7d588aChris Lattner#include "llvm/Target/TargetInstrInfo.h"
32f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman#include "llvm/Target/TargetMachine.h"
33f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman#include "llvm/Target/TargetOptions.h"
34551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/CommandLine.h"
35551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/Debug.h"
36ae232e7a1055033436370c0b3aecf054fa44d5e7Nate Begeman#include "llvm/Support/MathExtras.h"
37551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/ADT/STLExtras.h"
38f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman#include <cstdlib>
39f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukmanusing namespace llvm;
40f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman
41369503f8412bba4a0138074c97107c09cc4513e0Chris Lattner/// getRegisterNumbering - Given the enum value for some register, e.g.
42369503f8412bba4a0138074c97107c09cc4513e0Chris Lattner/// PPC::F14, return the number that it corresponds to (e.g. 14).
43369503f8412bba4a0138074c97107c09cc4513e0Chris Lattnerunsigned PPCRegisterInfo::getRegisterNumbering(unsigned RegEnum) {
44be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  using namespace PPC;
45369503f8412bba4a0138074c97107c09cc4513e0Chris Lattner  switch (RegEnum) {
46be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R0 :  case X0 :  case F0 :  case V0 : case CR0:  return  0;
47be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R1 :  case X1 :  case F1 :  case V1 : case CR1:  return  1;
48be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R2 :  case X2 :  case F2 :  case V2 : case CR2:  return  2;
49be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R3 :  case X3 :  case F3 :  case V3 : case CR3:  return  3;
50be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R4 :  case X4 :  case F4 :  case V4 : case CR4:  return  4;
51be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R5 :  case X5 :  case F5 :  case V5 : case CR5:  return  5;
52be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R6 :  case X6 :  case F6 :  case V6 : case CR6:  return  6;
53be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R7 :  case X7 :  case F7 :  case V7 : case CR7:  return  7;
54be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R8 :  case X8 :  case F8 :  case V8 : return  8;
55be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R9 :  case X9 :  case F9 :  case V9 : return  9;
56be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R10:  case X10:  case F10:  case V10: return 10;
57be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R11:  case X11:  case F11:  case V11: return 11;
58be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R12:  case X12:  case F12:  case V12: return 12;
59be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R13:  case X13:  case F13:  case V13: return 13;
60be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R14:  case X14:  case F14:  case V14: return 14;
61be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R15:  case X15:  case F15:  case V15: return 15;
62be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R16:  case X16:  case F16:  case V16: return 16;
63be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R17:  case X17:  case F17:  case V17: return 17;
64be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R18:  case X18:  case F18:  case V18: return 18;
65be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R19:  case X19:  case F19:  case V19: return 19;
66be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R20:  case X20:  case F20:  case V20: return 20;
67be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R21:  case X21:  case F21:  case V21: return 21;
68be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R22:  case X22:  case F22:  case V22: return 22;
69be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R23:  case X23:  case F23:  case V23: return 23;
70be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R24:  case X24:  case F24:  case V24: return 24;
71be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R25:  case X25:  case F25:  case V25: return 25;
72be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R26:  case X26:  case F26:  case V26: return 26;
73be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R27:  case X27:  case F27:  case V27: return 27;
74be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R28:  case X28:  case F28:  case V28: return 28;
75be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R29:  case X29:  case F29:  case V29: return 29;
76be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R30:  case X30:  case F30:  case V30: return 30;
77be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  case R31:  case X31:  case F31:  case V31: return 31;
78be6a039ad4c6314176b0834c341a25504fded32eChris Lattner  default:
79f5da13367f88f06e3b585dc2263ab6e9ca6c4bf8Bill Wendling    cerr << "Unhandled reg in PPCRegisterInfo::getRegisterNumbering!\n";
80be6a039ad4c6314176b0834c341a25504fded32eChris Lattner    abort();
81369503f8412bba4a0138074c97107c09cc4513e0Chris Lattner  }
82369503f8412bba4a0138074c97107c09cc4513e0Chris Lattner}
83369503f8412bba4a0138074c97107c09cc4513e0Chris Lattner
847ce45783531cfa81bfd7be561ea7e4738e8c6ca8Evan ChengPPCRegisterInfo::PPCRegisterInfo(const PPCSubtarget &ST,
857ce45783531cfa81bfd7be561ea7e4738e8c6ca8Evan Cheng                                 const TargetInstrInfo &tii)
86804e06704261f233111913a047ef7f7dec1b8725Chris Lattner  : PPCGenRegisterInfo(PPC::ADJCALLSTACKDOWN, PPC::ADJCALLSTACKUP),
877ce45783531cfa81bfd7be561ea7e4738e8c6ca8Evan Cheng    Subtarget(ST), TII(tii) {
88b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman  ImmToIdxMap[PPC::LD]   = PPC::LDX;    ImmToIdxMap[PPC::STD]  = PPC::STDX;
89f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  ImmToIdxMap[PPC::LBZ]  = PPC::LBZX;   ImmToIdxMap[PPC::STB]  = PPC::STBX;
90f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  ImmToIdxMap[PPC::LHZ]  = PPC::LHZX;   ImmToIdxMap[PPC::LHA]  = PPC::LHAX;
91f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  ImmToIdxMap[PPC::LWZ]  = PPC::LWZX;   ImmToIdxMap[PPC::LWA]  = PPC::LWAX;
92f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  ImmToIdxMap[PPC::LFS]  = PPC::LFSX;   ImmToIdxMap[PPC::LFD]  = PPC::LFDX;
93f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  ImmToIdxMap[PPC::STH]  = PPC::STHX;   ImmToIdxMap[PPC::STW]  = PPC::STWX;
94f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  ImmToIdxMap[PPC::STFS] = PPC::STFSX;  ImmToIdxMap[PPC::STFD] = PPC::STFDX;
951d9d7427c4a4e3c7bdcfd1f725447f355e509c20Nate Begeman  ImmToIdxMap[PPC::ADDI] = PPC::ADD4;
96c88fa749eb85371f54917446b69eb89527fd12b7Chris Lattner  ImmToIdxMap[PPC::ADDI8] = PPC::ADD8;
97f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman}
98f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman
99b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukmanvoid
10021e463b2bf864671a87ebe386cb100ef9349a540Nate BegemanPPCRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
10121e463b2bf864671a87ebe386cb100ef9349a540Nate Begeman                                     MachineBasicBlock::iterator MI,
10221e463b2bf864671a87ebe386cb100ef9349a540Nate Begeman                                     unsigned SrcReg, int FrameIdx,
10321e463b2bf864671a87ebe386cb100ef9349a540Nate Begeman                                     const TargetRegisterClass *RC) const {
1046a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner  if (RC == PPC::GPRCRegisterClass) {
1056a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner    if (SrcReg != PPC::LR) {
106c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      addFrameReference(BuildMI(MBB, MI, TII.get(PPC::STW)).addReg(SrcReg),
107c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng                        FrameIdx);
1086a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner    } else {
1096a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner      // FIXME: this spills LR immediately to memory in one step.  To do this,
1106a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner      // we use R11, which we know cannot be used in the prolog/epilog.  This is
1116a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner      // a hack.
112c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      BuildMI(MBB, MI, TII.get(PPC::MFLR), PPC::R11);
113c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      addFrameReference(BuildMI(MBB, MI, TII.get(PPC::STW)).addReg(PPC::R11),
1146a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner                        FrameIdx);
1156a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner    }
1166a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner  } else if (RC == PPC::G8RCRegisterClass) {
1176a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner    if (SrcReg != PPC::LR8) {
118c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      addFrameReference(BuildMI(MBB, MI, TII.get(PPC::STD)).addReg(SrcReg),
119c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng                        FrameIdx);
1206a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner    } else {
1216a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner      // FIXME: this spills LR immediately to memory in one step.  To do this,
1226a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner      // we use R11, which we know cannot be used in the prolog/epilog.  This is
1236a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner      // a hack.
124c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      BuildMI(MBB, MI, TII.get(PPC::MFLR8), PPC::X11);
125c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      addFrameReference(BuildMI(MBB, MI, TII.get(PPC::STD)).addReg(PPC::X11),
1266a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner                        FrameIdx);
1276a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner    }
1286a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner  } else if (RC == PPC::F8RCRegisterClass) {
129c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    addFrameReference(BuildMI(MBB, MI, TII.get(PPC::STFD)).addReg(SrcReg),
130c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng                      FrameIdx);
1316a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner  } else if (RC == PPC::F4RCRegisterClass) {
132c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    addFrameReference(BuildMI(MBB, MI, TII.get(PPC::STFS)).addReg(SrcReg),
133c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng                      FrameIdx);
1341d9d7427c4a4e3c7bdcfd1f725447f355e509c20Nate Begeman  } else if (RC == PPC::CRRCRegisterClass) {
135e67304fb7880bd55d194d68b827c0eb2366c0a91Chris Lattner    // FIXME: We use R0 here, because it isn't available for RA.
136b47e0897a090d31d952957ba873db6c1e487b50eChris Lattner    // We need to store the CR in the low 4-bits of the saved value.  First,
137b47e0897a090d31d952957ba873db6c1e487b50eChris Lattner    // issue a MFCR to save all of the CRBits.
138c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, MI, TII.get(PPC::MFCR), PPC::R0);
139b47e0897a090d31d952957ba873db6c1e487b50eChris Lattner
140b47e0897a090d31d952957ba873db6c1e487b50eChris Lattner    // If the saved register wasn't CR0, shift the bits left so that they are in
141b47e0897a090d31d952957ba873db6c1e487b50eChris Lattner    // CR0's slot.
142b47e0897a090d31d952957ba873db6c1e487b50eChris Lattner    if (SrcReg != PPC::CR0) {
143b47e0897a090d31d952957ba873db6c1e487b50eChris Lattner      unsigned ShiftBits = PPCRegisterInfo::getRegisterNumbering(SrcReg)*4;
144e67304fb7880bd55d194d68b827c0eb2366c0a91Chris Lattner      // rlwinm r0, r0, ShiftBits, 0, 31.
145c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      BuildMI(MBB, MI, TII.get(PPC::RLWINM), PPC::R0)
146e67304fb7880bd55d194d68b827c0eb2366c0a91Chris Lattner        .addReg(PPC::R0).addImm(ShiftBits).addImm(0).addImm(31);
147b47e0897a090d31d952957ba873db6c1e487b50eChris Lattner    }
148b47e0897a090d31d952957ba873db6c1e487b50eChris Lattner
149c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    addFrameReference(BuildMI(MBB, MI, TII.get(PPC::STW)).addReg(PPC::R0),
150c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng                      FrameIdx);
1519c09c9ec9dab61450800b42cbf746164aa076b88Chris Lattner  } else if (RC == PPC::VRRCRegisterClass) {
1529c09c9ec9dab61450800b42cbf746164aa076b88Chris Lattner    // We don't have indexed addressing for vector loads.  Emit:
1539c09c9ec9dab61450800b42cbf746164aa076b88Chris Lattner    // R11 = ADDI FI#
1549c09c9ec9dab61450800b42cbf746164aa076b88Chris Lattner    // Dest = LVX R0, R11
1559c09c9ec9dab61450800b42cbf746164aa076b88Chris Lattner    //
1569c09c9ec9dab61450800b42cbf746164aa076b88Chris Lattner    // FIXME: We use R0 here, because it isn't available for RA.
157c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    addFrameReference(BuildMI(MBB, MI, TII.get(PPC::ADDI), PPC::R0),
158c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng                      FrameIdx, 0, 0);
159c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, MI, TII.get(PPC::STVX))
1609c09c9ec9dab61450800b42cbf746164aa076b88Chris Lattner      .addReg(SrcReg).addReg(PPC::R0).addReg(PPC::R0);
161f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  } else {
162919c032fa4511468aadc6f50d6ed9c50890710b3Chris Lattner    assert(0 && "Unknown regclass!");
163919c032fa4511468aadc6f50d6ed9c50890710b3Chris Lattner    abort();
164f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  }
165f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman}
166f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman
167f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukmanvoid
16821e463b2bf864671a87ebe386cb100ef9349a540Nate BegemanPPCRegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
1696a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner                                      MachineBasicBlock::iterator MI,
1706a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner                                      unsigned DestReg, int FrameIdx,
1716a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner                                      const TargetRegisterClass *RC) const {
1726a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner  if (RC == PPC::GPRCRegisterClass) {
1736a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner    if (DestReg != PPC::LR) {
174c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      addFrameReference(BuildMI(MBB, MI, TII.get(PPC::LWZ), DestReg), FrameIdx);
1756a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner    } else {
176c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      addFrameReference(BuildMI(MBB, MI, TII.get(PPC::LWZ), PPC::R11),FrameIdx);
177c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      BuildMI(MBB, MI, TII.get(PPC::MTLR)).addReg(PPC::R11);
1786a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner    }
1796a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner  } else if (RC == PPC::G8RCRegisterClass) {
1806a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner    if (DestReg != PPC::LR8) {
181c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      addFrameReference(BuildMI(MBB, MI, TII.get(PPC::LD), DestReg), FrameIdx);
1826a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner    } else {
183c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      addFrameReference(BuildMI(MBB, MI, TII.get(PPC::LD), PPC::R11), FrameIdx);
184c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      BuildMI(MBB, MI, TII.get(PPC::MTLR8)).addReg(PPC::R11);
1856a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner    }
1866a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner  } else if (RC == PPC::F8RCRegisterClass) {
187c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    addFrameReference(BuildMI(MBB, MI, TII.get(PPC::LFD), DestReg), FrameIdx);
1886a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner  } else if (RC == PPC::F4RCRegisterClass) {
189c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    addFrameReference(BuildMI(MBB, MI, TII.get(PPC::LFS), DestReg), FrameIdx);
1901d9d7427c4a4e3c7bdcfd1f725447f355e509c20Nate Begeman  } else if (RC == PPC::CRRCRegisterClass) {
191e67304fb7880bd55d194d68b827c0eb2366c0a91Chris Lattner    // FIXME: We use R0 here, because it isn't available for RA.
192c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    addFrameReference(BuildMI(MBB, MI, TII.get(PPC::LWZ), PPC::R0), FrameIdx);
193b47e0897a090d31d952957ba873db6c1e487b50eChris Lattner
194b47e0897a090d31d952957ba873db6c1e487b50eChris Lattner    // If the reloaded register isn't CR0, shift the bits right so that they are
195b47e0897a090d31d952957ba873db6c1e487b50eChris Lattner    // in the right CR's slot.
196b47e0897a090d31d952957ba873db6c1e487b50eChris Lattner    if (DestReg != PPC::CR0) {
197b47e0897a090d31d952957ba873db6c1e487b50eChris Lattner      unsigned ShiftBits = PPCRegisterInfo::getRegisterNumbering(DestReg)*4;
198b47e0897a090d31d952957ba873db6c1e487b50eChris Lattner      // rlwinm r11, r11, 32-ShiftBits, 0, 31.
199c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      BuildMI(MBB, MI, TII.get(PPC::RLWINM), PPC::R0)
200e67304fb7880bd55d194d68b827c0eb2366c0a91Chris Lattner        .addReg(PPC::R0).addImm(32-ShiftBits).addImm(0).addImm(31);
201b47e0897a090d31d952957ba873db6c1e487b50eChris Lattner    }
202b47e0897a090d31d952957ba873db6c1e487b50eChris Lattner
203c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, MI, TII.get(PPC::MTCRF), DestReg).addReg(PPC::R0);
2049c09c9ec9dab61450800b42cbf746164aa076b88Chris Lattner  } else if (RC == PPC::VRRCRegisterClass) {
2059c09c9ec9dab61450800b42cbf746164aa076b88Chris Lattner    // We don't have indexed addressing for vector loads.  Emit:
2069c09c9ec9dab61450800b42cbf746164aa076b88Chris Lattner    // R11 = ADDI FI#
2079c09c9ec9dab61450800b42cbf746164aa076b88Chris Lattner    // Dest = LVX R0, R11
2089c09c9ec9dab61450800b42cbf746164aa076b88Chris Lattner    //
2099c09c9ec9dab61450800b42cbf746164aa076b88Chris Lattner    // FIXME: We use R0 here, because it isn't available for RA.
210c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    addFrameReference(BuildMI(MBB, MI, TII.get(PPC::ADDI), PPC::R0),
211c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng                      FrameIdx, 0, 0);
212c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, MI, TII.get(PPC::LVX),DestReg).addReg(PPC::R0).addReg(PPC::R0);
213f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  } else {
214919c032fa4511468aadc6f50d6ed9c50890710b3Chris Lattner    assert(0 && "Unknown regclass!");
215919c032fa4511468aadc6f50d6ed9c50890710b3Chris Lattner    abort();
216f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  }
217f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman}
218f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman
21921e463b2bf864671a87ebe386cb100ef9349a540Nate Begemanvoid PPCRegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
22021e463b2bf864671a87ebe386cb100ef9349a540Nate Begeman                                   MachineBasicBlock::iterator MI,
22121e463b2bf864671a87ebe386cb100ef9349a540Nate Begeman                                   unsigned DestReg, unsigned SrcReg,
22221e463b2bf864671a87ebe386cb100ef9349a540Nate Begeman                                   const TargetRegisterClass *RC) const {
2231d9d7427c4a4e3c7bdcfd1f725447f355e509c20Nate Begeman  if (RC == PPC::GPRCRegisterClass) {
224c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, MI, TII.get(PPC::OR), DestReg).addReg(SrcReg).addReg(SrcReg);
2251d9d7427c4a4e3c7bdcfd1f725447f355e509c20Nate Begeman  } else if (RC == PPC::G8RCRegisterClass) {
226c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, MI, TII.get(PPC::OR8), DestReg).addReg(SrcReg).addReg(SrcReg);
2271d9d7427c4a4e3c7bdcfd1f725447f355e509c20Nate Begeman  } else if (RC == PPC::F4RCRegisterClass) {
228c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, MI, TII.get(PPC::FMRS), DestReg).addReg(SrcReg);
2291d9d7427c4a4e3c7bdcfd1f725447f355e509c20Nate Begeman  } else if (RC == PPC::F8RCRegisterClass) {
230c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, MI, TII.get(PPC::FMRD), DestReg).addReg(SrcReg);
2311d9d7427c4a4e3c7bdcfd1f725447f355e509c20Nate Begeman  } else if (RC == PPC::CRRCRegisterClass) {
232c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, MI, TII.get(PPC::MCRF), DestReg).addReg(SrcReg);
233335fd3c7c2057b4e5fedb3161df44d7bc1759791Chris Lattner  } else if (RC == PPC::VRRCRegisterClass) {
234c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, MI, TII.get(PPC::VOR), DestReg).addReg(SrcReg).addReg(SrcReg);
2357af0248af47fbd86ec65d308adda22ec367accc4Nate Begeman  } else {
236f5da13367f88f06e3b585dc2263ab6e9ca6c4bf8Bill Wendling    cerr << "Attempt to copy register that is not GPR or FPR";
237f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman    abort();
238f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  }
239f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman}
240f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman
241c2b861da18c54a4252fecba866341e1513fa18ccEvan Chengconst unsigned* PPCRegisterInfo::getCalleeSavedRegs() const {
242804e06704261f233111913a047ef7f7dec1b8725Chris Lattner  // 32-bit Darwin calling convention.
243c2b861da18c54a4252fecba866341e1513fa18ccEvan Cheng  static const unsigned Darwin32_CalleeSavedRegs[] = {
2442f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey              PPC::R13, PPC::R14, PPC::R15,
245804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::R16, PPC::R17, PPC::R18, PPC::R19,
246804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::R20, PPC::R21, PPC::R22, PPC::R23,
247804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::R24, PPC::R25, PPC::R26, PPC::R27,
248804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::R28, PPC::R29, PPC::R30, PPC::R31,
249804e06704261f233111913a047ef7f7dec1b8725Chris Lattner
250804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::F14, PPC::F15, PPC::F16, PPC::F17,
251804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::F18, PPC::F19, PPC::F20, PPC::F21,
252804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::F22, PPC::F23, PPC::F24, PPC::F25,
253804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::F26, PPC::F27, PPC::F28, PPC::F29,
254804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::F30, PPC::F31,
255804e06704261f233111913a047ef7f7dec1b8725Chris Lattner
256804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::CR2, PPC::CR3, PPC::CR4,
257804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::V20, PPC::V21, PPC::V22, PPC::V23,
258804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::V24, PPC::V25, PPC::V26, PPC::V27,
259804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::V28, PPC::V29, PPC::V30, PPC::V31,
260804e06704261f233111913a047ef7f7dec1b8725Chris Lattner
261804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::LR,  0
262804e06704261f233111913a047ef7f7dec1b8725Chris Lattner  };
263804e06704261f233111913a047ef7f7dec1b8725Chris Lattner  // 64-bit Darwin calling convention.
264c2b861da18c54a4252fecba866341e1513fa18ccEvan Cheng  static const unsigned Darwin64_CalleeSavedRegs[] = {
265bdc571b7d578091059aa7bc5c3a190ceb70f9542Chris Lattner    PPC::X14, PPC::X15,
266804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::X16, PPC::X17, PPC::X18, PPC::X19,
267804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::X20, PPC::X21, PPC::X22, PPC::X23,
268804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::X24, PPC::X25, PPC::X26, PPC::X27,
269804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::X28, PPC::X29, PPC::X30, PPC::X31,
270804e06704261f233111913a047ef7f7dec1b8725Chris Lattner
271804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::F14, PPC::F15, PPC::F16, PPC::F17,
272804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::F18, PPC::F19, PPC::F20, PPC::F21,
273804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::F22, PPC::F23, PPC::F24, PPC::F25,
274804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::F26, PPC::F27, PPC::F28, PPC::F29,
2750f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng    PPC::F30, PPC::F31,
276804e06704261f233111913a047ef7f7dec1b8725Chris Lattner
277804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::CR2, PPC::CR3, PPC::CR4,
278804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::V20, PPC::V21, PPC::V22, PPC::V23,
279804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::V24, PPC::V25, PPC::V26, PPC::V27,
280804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    PPC::V28, PPC::V29, PPC::V30, PPC::V31,
281804e06704261f233111913a047ef7f7dec1b8725Chris Lattner
2826a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner    PPC::LR8,  0
2830f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng  };
284804e06704261f233111913a047ef7f7dec1b8725Chris Lattner
285c2b861da18c54a4252fecba866341e1513fa18ccEvan Cheng  return Subtarget.isPPC64() ? Darwin64_CalleeSavedRegs :
286c2b861da18c54a4252fecba866341e1513fa18ccEvan Cheng                               Darwin32_CalleeSavedRegs;
2870f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng}
2880f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng
2890f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Chengconst TargetRegisterClass* const*
290c2b861da18c54a4252fecba866341e1513fa18ccEvan ChengPPCRegisterInfo::getCalleeSavedRegClasses() const {
291804e06704261f233111913a047ef7f7dec1b8725Chris Lattner  // 32-bit Darwin calling convention.
292c2b861da18c54a4252fecba866341e1513fa18ccEvan Cheng  static const TargetRegisterClass * const Darwin32_CalleeSavedRegClasses[] = {
2932f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey                       &PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,
294804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,
295804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,
296804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,
297804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,
298804e06704261f233111913a047ef7f7dec1b8725Chris Lattner
299804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,
300804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,
301804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,
302804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,
303804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::F8RCRegClass,&PPC::F8RCRegClass,
304804e06704261f233111913a047ef7f7dec1b8725Chris Lattner
305804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::CRRCRegClass,&PPC::CRRCRegClass,&PPC::CRRCRegClass,
306804e06704261f233111913a047ef7f7dec1b8725Chris Lattner
307804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,
308804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,
309804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,
310804e06704261f233111913a047ef7f7dec1b8725Chris Lattner
311804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::GPRCRegClass, 0
312804e06704261f233111913a047ef7f7dec1b8725Chris Lattner  };
313804e06704261f233111913a047ef7f7dec1b8725Chris Lattner
314804e06704261f233111913a047ef7f7dec1b8725Chris Lattner  // 64-bit Darwin calling convention.
315c2b861da18c54a4252fecba866341e1513fa18ccEvan Cheng  static const TargetRegisterClass * const Darwin64_CalleeSavedRegClasses[] = {
316bdc571b7d578091059aa7bc5c3a190ceb70f9542Chris Lattner    &PPC::G8RCRegClass,&PPC::G8RCRegClass,
317804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,
318804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,
319804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,
320804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,
321804e06704261f233111913a047ef7f7dec1b8725Chris Lattner
322804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,
323804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,
324804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,
325804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,
326804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::F8RCRegClass,&PPC::F8RCRegClass,
327804e06704261f233111913a047ef7f7dec1b8725Chris Lattner
328804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::CRRCRegClass,&PPC::CRRCRegClass,&PPC::CRRCRegClass,
329804e06704261f233111913a047ef7f7dec1b8725Chris Lattner
330804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,
331804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,
332804e06704261f233111913a047ef7f7dec1b8725Chris Lattner    &PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,
333804e06704261f233111913a047ef7f7dec1b8725Chris Lattner
3346a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner    &PPC::G8RCRegClass, 0
3350f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng  };
336804e06704261f233111913a047ef7f7dec1b8725Chris Lattner
337c2b861da18c54a4252fecba866341e1513fa18ccEvan Cheng  return Subtarget.isPPC64() ? Darwin64_CalleeSavedRegClasses :
338c2b861da18c54a4252fecba866341e1513fa18ccEvan Cheng                               Darwin32_CalleeSavedRegClasses;
3390f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng}
3400f3ac8d8d4ce23eb2ae6f9d850f389250874eea5Evan Cheng
341f38df04c3a0c2aa766fa50b254d2d0fc743f8152Chris Lattner/// foldMemoryOperand - PowerPC (like most RISC's) can only fold spills into
342f38df04c3a0c2aa766fa50b254d2d0fc743f8152Chris Lattner/// copy instructions, turning them into load/store instructions.
34321e463b2bf864671a87ebe386cb100ef9349a540Nate BegemanMachineInstr *PPCRegisterInfo::foldMemoryOperand(MachineInstr *MI,
34421e463b2bf864671a87ebe386cb100ef9349a540Nate Begeman                                                 unsigned OpNum,
34521e463b2bf864671a87ebe386cb100ef9349a540Nate Begeman                                                 int FrameIndex) const {
346f38df04c3a0c2aa766fa50b254d2d0fc743f8152Chris Lattner  // Make sure this is a reg-reg copy.  Note that we can't handle MCRF, because
347f38df04c3a0c2aa766fa50b254d2d0fc743f8152Chris Lattner  // it takes more than one instruction to store it.
348f38df04c3a0c2aa766fa50b254d2d0fc743f8152Chris Lattner  unsigned Opc = MI->getOpcode();
3496ce7dc2a97260eea5fba414332796464912b9359Evan Cheng
3506ce7dc2a97260eea5fba414332796464912b9359Evan Cheng  MachineInstr *NewMI = NULL;
351b410dc99774d52b4491750dab10b91cca1d661d8Chris Lattner  if ((Opc == PPC::OR &&
352f38df04c3a0c2aa766fa50b254d2d0fc743f8152Chris Lattner       MI->getOperand(1).getReg() == MI->getOperand(2).getReg())) {
353f38df04c3a0c2aa766fa50b254d2d0fc743f8152Chris Lattner    if (OpNum == 0) {  // move -> store
354f38df04c3a0c2aa766fa50b254d2d0fc743f8152Chris Lattner      unsigned InReg = MI->getOperand(1).getReg();
355c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      NewMI = addFrameReference(BuildMI(TII.get(PPC::STW)).addReg(InReg),
356c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng                                FrameIndex);
357c9fe7508a5e072479d4ab5711c60aa5142c64f10Chris Lattner    } else {           // move -> load
358f38df04c3a0c2aa766fa50b254d2d0fc743f8152Chris Lattner      unsigned OutReg = MI->getOperand(0).getReg();
359c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      NewMI = addFrameReference(BuildMI(TII.get(PPC::LWZ), OutReg),
360c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng                                FrameIndex);
361f38df04c3a0c2aa766fa50b254d2d0fc743f8152Chris Lattner    }
3621d9d7427c4a4e3c7bdcfd1f725447f355e509c20Nate Begeman  } else if ((Opc == PPC::OR8 &&
3631d9d7427c4a4e3c7bdcfd1f725447f355e509c20Nate Begeman              MI->getOperand(1).getReg() == MI->getOperand(2).getReg())) {
3641d9d7427c4a4e3c7bdcfd1f725447f355e509c20Nate Begeman    if (OpNum == 0) {  // move -> store
3651d9d7427c4a4e3c7bdcfd1f725447f355e509c20Nate Begeman      unsigned InReg = MI->getOperand(1).getReg();
366c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      NewMI = addFrameReference(BuildMI(TII.get(PPC::STD)).addReg(InReg),
367c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng                                FrameIndex);
3681d9d7427c4a4e3c7bdcfd1f725447f355e509c20Nate Begeman    } else {           // move -> load
3691d9d7427c4a4e3c7bdcfd1f725447f355e509c20Nate Begeman      unsigned OutReg = MI->getOperand(0).getReg();
370c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      NewMI = addFrameReference(BuildMI(TII.get(PPC::LD), OutReg), FrameIndex);
3711d9d7427c4a4e3c7bdcfd1f725447f355e509c20Nate Begeman    }
372919c032fa4511468aadc6f50d6ed9c50890710b3Chris Lattner  } else if (Opc == PPC::FMRD) {
373c9fe7508a5e072479d4ab5711c60aa5142c64f10Chris Lattner    if (OpNum == 0) {  // move -> store
374c9fe7508a5e072479d4ab5711c60aa5142c64f10Chris Lattner      unsigned InReg = MI->getOperand(1).getReg();
375c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      NewMI = addFrameReference(BuildMI(TII.get(PPC::STFD)).addReg(InReg),
376c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng                                FrameIndex);
377c9fe7508a5e072479d4ab5711c60aa5142c64f10Chris Lattner    } else {           // move -> load
378c9fe7508a5e072479d4ab5711c60aa5142c64f10Chris Lattner      unsigned OutReg = MI->getOperand(0).getReg();
379c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      NewMI = addFrameReference(BuildMI(TII.get(PPC::LFD), OutReg), FrameIndex);
380c9fe7508a5e072479d4ab5711c60aa5142c64f10Chris Lattner    }
381919c032fa4511468aadc6f50d6ed9c50890710b3Chris Lattner  } else if (Opc == PPC::FMRS) {
382919c032fa4511468aadc6f50d6ed9c50890710b3Chris Lattner    if (OpNum == 0) {  // move -> store
383919c032fa4511468aadc6f50d6ed9c50890710b3Chris Lattner      unsigned InReg = MI->getOperand(1).getReg();
384c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      NewMI = addFrameReference(BuildMI(TII.get(PPC::STFS)).addReg(InReg),
385c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng                                FrameIndex);
386919c032fa4511468aadc6f50d6ed9c50890710b3Chris Lattner    } else {           // move -> load
387919c032fa4511468aadc6f50d6ed9c50890710b3Chris Lattner      unsigned OutReg = MI->getOperand(0).getReg();
388c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      NewMI = addFrameReference(BuildMI(TII.get(PPC::LFS), OutReg), FrameIndex);
389919c032fa4511468aadc6f50d6ed9c50890710b3Chris Lattner    }
390f38df04c3a0c2aa766fa50b254d2d0fc743f8152Chris Lattner  }
3916ce7dc2a97260eea5fba414332796464912b9359Evan Cheng
3926ce7dc2a97260eea5fba414332796464912b9359Evan Cheng  if (NewMI)
3936ce7dc2a97260eea5fba414332796464912b9359Evan Cheng    NewMI->copyKillDeadInfo(MI);
3946ce7dc2a97260eea5fba414332796464912b9359Evan Cheng  return NewMI;
395f38df04c3a0c2aa766fa50b254d2d0fc743f8152Chris Lattner}
396f38df04c3a0c2aa766fa50b254d2d0fc743f8152Chris Lattner
397f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman//===----------------------------------------------------------------------===//
398f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman// Stack Frame Processing methods
399f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman//===----------------------------------------------------------------------===//
400f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman
4012f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey// needsFP - Return true if the specified function should have a dedicated frame
402f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman// pointer register.  This is true if the function has variable sized allocas or
403f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman// if frame pointer elimination is disabled.
404f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman//
4052f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskeystatic bool needsFP(const MachineFunction &MF) {
4064f91a4c497fb1032550b7f163004efc5fce1d7f1Chris Lattner  const MachineFrameInfo *MFI = MF.getFrameInfo();
407030514cd96e9b8bb08fd9585d890bd7a5f0dbb77Nate Begeman  return NoFramePointerElim || MFI->hasVarSizedObjects();
408f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman}
409f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman
4102f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey// hasFP - Return true if the specified function actually has a dedicated frame
4112f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey// pointer register.  This is true if the function needs a frame pointer and has
4122f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey// a non-zero stack size.
413dc77540d9506dc151d79b94bae88bd841880ef37Evan Chengbool PPCRegisterInfo::hasFP(const MachineFunction &MF) const {
4142f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  const MachineFrameInfo *MFI = MF.getFrameInfo();
4152f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  return MFI->getStackSize() && needsFP(MF);
4162f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey}
4172f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey
41851fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey/// usesLR - Returns if the link registers (LR) has been used in the function.
41951fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey///
42051fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskeybool PPCRegisterInfo::usesLR(MachineFunction &MF) const {
42151fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  const bool *PhysRegsUsed = MF.getUsedPhysregs();
42251fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  return PhysRegsUsed[getRARegister()];
42351fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey}
42451fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey
42521e463b2bf864671a87ebe386cb100ef9349a540Nate Begemanvoid PPCRegisterInfo::
426f2ccb77ee9d8ab35866dae111fa36929689c7511Misha BrukmaneliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
427f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman                              MachineBasicBlock::iterator I) const {
4282f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
429f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  MBB.erase(I);
430f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman}
431f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman
4322f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey/// LowerDynamicAlloc - Generate the code for allocating an object in the
4332f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey/// current frame.  The sequence of code with be in the general form
4342f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey///
4352f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey///   addi   R0, SP, #frameSize ; get the address of the previous frame
4362f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey///   stwxu  R0, SP, Rnegsize   ; add and update the SP with the negated size
4372f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey///   addi   Rnew, SP, #maxCalFrameSize ; get the top of the allocation
4382f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey///
4392f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskeyvoid PPCRegisterInfo::lowerDynamicAlloc(MachineBasicBlock::iterator II) const {
4402f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Get the instruction.
4412f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  MachineInstr &MI = *II;
4422f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Get the instruction's basic block.
4432f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  MachineBasicBlock &MBB = *MI.getParent();
4442f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Get the basic block's function.
4452f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  MachineFunction &MF = *MBB.getParent();
4462f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Get the frame info.
4472f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  MachineFrameInfo *MFI = MF.getFrameInfo();
4482f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Determine whether 64-bit pointers are used.
4492f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  bool LP64 = Subtarget.isPPC64();
4502f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey
4512f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Determine the maximum call stack size.  maxCallFrameSize may be
4522f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // less than the minimum.
4532f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  unsigned maxCallFrameSize = MFI->getMaxCallFrameSize();
4542f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  unsigned getMinCallFrameSize =
4552f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey    PPCFrameInfo::getMinCallFrameSize(LP64);
4562f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  maxCallFrameSize = std::max(maxCallFrameSize, getMinCallFrameSize);
4572f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Get the total frame size.
4582f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  unsigned FrameSize = MFI->getStackSize();
4592f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey
4602f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Get stack alignments.
4612f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
4622f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  unsigned MaxAlign = MFI->getMaxAlignment();
463d6fa8c166ace05779ebefe511c615223b12fe7dbJim Laskey  assert(MaxAlign <= TargetAlign &&
464d6fa8c166ace05779ebefe511c615223b12fe7dbJim Laskey         "Dynamic alloca with large aligns not supported");
4652f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey
4662f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Determine the previous frame's address.  If FrameSize can't be
4672f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // represented as 16 bits or we need special alignment, then we load the
4682f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // previous frame's address from 0(SP).  Why not do an addis of the hi?
4692f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Because R0 is our only safe tmp register and addi/addis treat R0 as zero.
4702f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Constructing the constant and adding would take 3 instructions.
4712f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Fortunately, a frame greater than 32K is rare.
4722f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  if (MaxAlign < TargetAlign && isInt16(FrameSize)) {
473c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, II, TII.get(PPC::ADDI), PPC::R0)
4742f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey      .addReg(PPC::R31)
4752f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey      .addImm(FrameSize);
4762f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  } else if (LP64) {
477c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, II, TII.get(PPC::LD), PPC::X0)
4782f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey      .addImm(0)
4792f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey      .addReg(PPC::X1);
4802f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  } else {
481c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, II, TII.get(PPC::LWZ), PPC::R0)
4822f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey      .addImm(0)
4832f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey      .addReg(PPC::R1);
4842f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  }
4852f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey
4862f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Grow the stack and update the stack pointer link, then
4872f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // determine the address of new allocated space.
4882f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  if (LP64) {
489c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, II, TII.get(PPC::STDUX))
4902f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey      .addReg(PPC::X0)
4912f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey      .addReg(PPC::X1)
4922f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey      .addReg(MI.getOperand(1).getReg());
493c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, II, TII.get(PPC::ADDI8), MI.getOperand(0).getReg())
4942f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey      .addReg(PPC::X1)
4952f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey      .addImm(maxCallFrameSize);
4962f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  } else {
497c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, II, TII.get(PPC::STWUX))
4982f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey      .addReg(PPC::R0)
4992f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey      .addReg(PPC::R1)
5002f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey      .addReg(MI.getOperand(1).getReg());
501c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, II, TII.get(PPC::ADDI), MI.getOperand(0).getReg())
5022f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey      .addReg(PPC::R1)
5032f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey      .addImm(maxCallFrameSize);
5042f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  }
5052f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey
5062f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Discard the DYNALLOC instruction.
5072f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  MBB.erase(II);
5082f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey}
5092f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey
510f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukmanvoid
51121e463b2bf864671a87ebe386cb100ef9349a540Nate BegemanPPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
5122f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Get the instruction.
513f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  MachineInstr &MI = *II;
5142f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Get the instruction's basic block.
515f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  MachineBasicBlock &MBB = *MI.getParent();
5162f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Get the basic block's function.
517f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  MachineFunction &MF = *MBB.getParent();
5182f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Get the frame info.
5192f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  MachineFrameInfo *MFI = MF.getFrameInfo();
520b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman
5212f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Find out which operand is the frame index.
5222f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  unsigned i = 0;
523f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  while (!MI.getOperand(i).isFrameIndex()) {
524f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman    ++i;
525f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman    assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
526f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  }
5272f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Take into account whether it's an add or mem instruction
5282f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  unsigned OffIdx = (i == 2) ? 1 : 2;
5292f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Get the frame index.
530f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  int FrameIndex = MI.getOperand(i).getFrameIndex();
5312f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey
5322f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Get the frame pointer save index.  Users of this index are primarily
5332f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // DYNALLOC instructions.
5342f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
5352f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  int FPSI = FI->getFramePointerSaveIndex();
5362f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Get the instruction opcode.
5372f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  unsigned OpC = MI.getOpcode();
5382f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey
5392f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Special case for dynamic alloca.
5402f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  if (FPSI && FrameIndex == FPSI &&
5412f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey      (OpC == PPC::DYNALLOC || OpC == PPC::DYNALLOC8)) {
5422f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey    lowerDynamicAlloc(II);
5432f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey    return;
5442f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  }
545f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman
546f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  // Replace the FrameIndex with base register with GPR1 (SP) or GPR31 (FP).
54709e460662a8d7328da1b938d5581a6ef3740b51dChris Lattner  MI.getOperand(i).ChangeToRegister(hasFP(MF) ? PPC::R31 : PPC::R1, false);
548f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman
5497ffa9abdadd7e51726240b6a8352abda8edde869Chris Lattner  // Figure out if the offset in the instruction is shifted right two bits. This
5507ffa9abdadd7e51726240b6a8352abda8edde869Chris Lattner  // is true for instructions like "STD", which the machine implicitly adds two
5517ffa9abdadd7e51726240b6a8352abda8edde869Chris Lattner  // low zeros to.
5527ffa9abdadd7e51726240b6a8352abda8edde869Chris Lattner  bool isIXAddr = false;
5532f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  switch (OpC) {
5547ffa9abdadd7e51726240b6a8352abda8edde869Chris Lattner  case PPC::LWA:
5557ffa9abdadd7e51726240b6a8352abda8edde869Chris Lattner  case PPC::LD:
5567ffa9abdadd7e51726240b6a8352abda8edde869Chris Lattner  case PPC::STD:
5577ffa9abdadd7e51726240b6a8352abda8edde869Chris Lattner  case PPC::STD_32:
5587ffa9abdadd7e51726240b6a8352abda8edde869Chris Lattner    isIXAddr = true;
5597ffa9abdadd7e51726240b6a8352abda8edde869Chris Lattner    break;
5607ffa9abdadd7e51726240b6a8352abda8edde869Chris Lattner  }
5617ffa9abdadd7e51726240b6a8352abda8edde869Chris Lattner
562f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  // Now add the frame object offset to the offset from r1.
5632f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  int Offset = MFI->getObjectOffset(FrameIndex);
5647ffa9abdadd7e51726240b6a8352abda8edde869Chris Lattner
5657ffa9abdadd7e51726240b6a8352abda8edde869Chris Lattner  if (!isIXAddr)
5667ffa9abdadd7e51726240b6a8352abda8edde869Chris Lattner    Offset += MI.getOperand(OffIdx).getImmedValue();
5677ffa9abdadd7e51726240b6a8352abda8edde869Chris Lattner  else
5687ffa9abdadd7e51726240b6a8352abda8edde869Chris Lattner    Offset += MI.getOperand(OffIdx).getImmedValue() << 2;
569f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman
570f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  // If we're not using a Frame Pointer that has been set to the value of the
571f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  // SP before having the stack size subtracted from it, then add the stack size
572f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  // to Offset to get the correct offset.
5732f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  Offset += MFI->getStackSize();
574b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman
5752f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  if (!isInt16(Offset)) {
576f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman    // Insert a set of r0 with the full offset value before the ld, st, or add
577c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, II, TII.get(PPC::LIS), PPC::R0).addImm(Offset >> 16);
578c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, II, TII.get(PPC::ORI), PPC::R0).addReg(PPC::R0).addImm(Offset);
579c6d48d36a349f593aab2194c141a1e24da1aec3eChris Lattner
580f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman    // convert into indexed form of the instruction
581f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman    // sth 0:rA, 1:imm 2:(rB) ==> sthx 0:rA, 2:rB, 1:r0
582f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman    // addi 0:rA 1:rB, 2, imm ==> add 0:rA, 1:rB, 2:r0
5832f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey    assert(ImmToIdxMap.count(OpC) &&
5841463019e84cea6857914cea30c0180ec7289f09fChris Lattner           "No indexed form of load or store available!");
5852f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey    unsigned NewOpcode = ImmToIdxMap.find(OpC)->second;
58612a447898a3c68c1a9489f71b82650b46244d00aEvan Cheng    MI.setInstrDescriptor(TII.get(NewOpcode));
58709e460662a8d7328da1b938d5581a6ef3740b51dChris Lattner    MI.getOperand(1).ChangeToRegister(MI.getOperand(i).getReg(), false);
58809e460662a8d7328da1b938d5581a6ef3740b51dChris Lattner    MI.getOperand(2).ChangeToRegister(PPC::R0, false);
589f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  } else {
5907ffa9abdadd7e51726240b6a8352abda8edde869Chris Lattner    if (isIXAddr) {
591841d12d9ac489ec33d933af96d77dd4fc2a4cee2Chris Lattner      assert((Offset & 3) == 0 && "Invalid frame offset!");
592841d12d9ac489ec33d933af96d77dd4fc2a4cee2Chris Lattner      Offset >>= 2;    // The actual encoded value has the low two bits zero.
593841d12d9ac489ec33d933af96d77dd4fc2a4cee2Chris Lattner    }
594e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner    MI.getOperand(OffIdx).ChangeToImmediate(Offset);
595f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  }
596f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman}
597f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman
598f7d2372b7407c7f8966df39a2b5a067c72bd6b9bChris Lattner/// VRRegNo - Map from a numbered VR register to its enum value.
599f7d2372b7407c7f8966df39a2b5a067c72bd6b9bChris Lattner///
600f7d2372b7407c7f8966df39a2b5a067c72bd6b9bChris Lattnerstatic const unsigned short VRRegNo[] = {
601b47e0897a090d31d952957ba873db6c1e487b50eChris Lattner PPC::V0 , PPC::V1 , PPC::V2 , PPC::V3 , PPC::V4 , PPC::V5 , PPC::V6 , PPC::V7 ,
602b47e0897a090d31d952957ba873db6c1e487b50eChris Lattner PPC::V8 , PPC::V9 , PPC::V10, PPC::V11, PPC::V12, PPC::V13, PPC::V14, PPC::V15,
603f7d2372b7407c7f8966df39a2b5a067c72bd6b9bChris Lattner PPC::V16, PPC::V17, PPC::V18, PPC::V19, PPC::V20, PPC::V21, PPC::V22, PPC::V23,
604f7d2372b7407c7f8966df39a2b5a067c72bd6b9bChris Lattner PPC::V24, PPC::V25, PPC::V26, PPC::V27, PPC::V28, PPC::V29, PPC::V30, PPC::V31
605f7d2372b7407c7f8966df39a2b5a067c72bd6b9bChris Lattner};
606f7d2372b7407c7f8966df39a2b5a067c72bd6b9bChris Lattner
607f9568d8700d5389799796262cde313bb5c7d588aChris Lattner/// RemoveVRSaveCode - We have found that this function does not need any code
608f9568d8700d5389799796262cde313bb5c7d588aChris Lattner/// to manipulate the VRSAVE register, even though it uses vector registers.
609f9568d8700d5389799796262cde313bb5c7d588aChris Lattner/// This can happen when the only registers used are known to be live in or out
610f9568d8700d5389799796262cde313bb5c7d588aChris Lattner/// of the function.  Remove all of the VRSAVE related code from the function.
611f9568d8700d5389799796262cde313bb5c7d588aChris Lattnerstatic void RemoveVRSaveCode(MachineInstr *MI) {
612f9568d8700d5389799796262cde313bb5c7d588aChris Lattner  MachineBasicBlock *Entry = MI->getParent();
613f9568d8700d5389799796262cde313bb5c7d588aChris Lattner  MachineFunction *MF = Entry->getParent();
614f9568d8700d5389799796262cde313bb5c7d588aChris Lattner
615f9568d8700d5389799796262cde313bb5c7d588aChris Lattner  // We know that the MTVRSAVE instruction immediately follows MI.  Remove it.
616f9568d8700d5389799796262cde313bb5c7d588aChris Lattner  MachineBasicBlock::iterator MBBI = MI;
617f9568d8700d5389799796262cde313bb5c7d588aChris Lattner  ++MBBI;
618f9568d8700d5389799796262cde313bb5c7d588aChris Lattner  assert(MBBI != Entry->end() && MBBI->getOpcode() == PPC::MTVRSAVE);
619f9568d8700d5389799796262cde313bb5c7d588aChris Lattner  MBBI->eraseFromParent();
620f9568d8700d5389799796262cde313bb5c7d588aChris Lattner
621f9568d8700d5389799796262cde313bb5c7d588aChris Lattner  bool RemovedAllMTVRSAVEs = true;
622f9568d8700d5389799796262cde313bb5c7d588aChris Lattner  // See if we can find and remove the MTVRSAVE instruction from all of the
623f9568d8700d5389799796262cde313bb5c7d588aChris Lattner  // epilog blocks.
624f9568d8700d5389799796262cde313bb5c7d588aChris Lattner  const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
625f9568d8700d5389799796262cde313bb5c7d588aChris Lattner  for (MachineFunction::iterator I = MF->begin(), E = MF->end(); I != E; ++I) {
626f9568d8700d5389799796262cde313bb5c7d588aChris Lattner    // If last instruction is a return instruction, add an epilogue
627f9568d8700d5389799796262cde313bb5c7d588aChris Lattner    if (!I->empty() && TII.isReturn(I->back().getOpcode())) {
628f9568d8700d5389799796262cde313bb5c7d588aChris Lattner      bool FoundIt = false;
629f9568d8700d5389799796262cde313bb5c7d588aChris Lattner      for (MBBI = I->end(); MBBI != I->begin(); ) {
630f9568d8700d5389799796262cde313bb5c7d588aChris Lattner        --MBBI;
631f9568d8700d5389799796262cde313bb5c7d588aChris Lattner        if (MBBI->getOpcode() == PPC::MTVRSAVE) {
632f9568d8700d5389799796262cde313bb5c7d588aChris Lattner          MBBI->eraseFromParent();  // remove it.
633f9568d8700d5389799796262cde313bb5c7d588aChris Lattner          FoundIt = true;
634f9568d8700d5389799796262cde313bb5c7d588aChris Lattner          break;
635f9568d8700d5389799796262cde313bb5c7d588aChris Lattner        }
636f9568d8700d5389799796262cde313bb5c7d588aChris Lattner      }
637f9568d8700d5389799796262cde313bb5c7d588aChris Lattner      RemovedAllMTVRSAVEs &= FoundIt;
638f9568d8700d5389799796262cde313bb5c7d588aChris Lattner    }
639f9568d8700d5389799796262cde313bb5c7d588aChris Lattner  }
640f9568d8700d5389799796262cde313bb5c7d588aChris Lattner
641f9568d8700d5389799796262cde313bb5c7d588aChris Lattner  // If we found and removed all MTVRSAVE instructions, remove the read of
642f9568d8700d5389799796262cde313bb5c7d588aChris Lattner  // VRSAVE as well.
643f9568d8700d5389799796262cde313bb5c7d588aChris Lattner  if (RemovedAllMTVRSAVEs) {
644f9568d8700d5389799796262cde313bb5c7d588aChris Lattner    MBBI = MI;
645f9568d8700d5389799796262cde313bb5c7d588aChris Lattner    assert(MBBI != Entry->begin() && "UPDATE_VRSAVE is first instr in block?");
646f9568d8700d5389799796262cde313bb5c7d588aChris Lattner    --MBBI;
647f9568d8700d5389799796262cde313bb5c7d588aChris Lattner    assert(MBBI->getOpcode() == PPC::MFVRSAVE && "VRSAVE instrs wandered?");
648f9568d8700d5389799796262cde313bb5c7d588aChris Lattner    MBBI->eraseFromParent();
649f9568d8700d5389799796262cde313bb5c7d588aChris Lattner  }
650f9568d8700d5389799796262cde313bb5c7d588aChris Lattner
651f9568d8700d5389799796262cde313bb5c7d588aChris Lattner  // Finally, nuke the UPDATE_VRSAVE.
652f9568d8700d5389799796262cde313bb5c7d588aChris Lattner  MI->eraseFromParent();
653f9568d8700d5389799796262cde313bb5c7d588aChris Lattner}
654f9568d8700d5389799796262cde313bb5c7d588aChris Lattner
6551877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner// HandleVRSaveUpdate - MI is the UPDATE_VRSAVE instruction introduced by the
6561877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner// instruction selector.  Based on the vector registers that have been used,
6571877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner// transform this into the appropriate ORI instruction.
658c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Chengstatic void HandleVRSaveUpdate(MachineInstr *MI, const bool *UsedRegs,
659c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng                               const TargetInstrInfo &TII) {
6601877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner  unsigned UsedRegMask = 0;
661f7d2372b7407c7f8966df39a2b5a067c72bd6b9bChris Lattner  for (unsigned i = 0; i != 32; ++i)
662f7d2372b7407c7f8966df39a2b5a067c72bd6b9bChris Lattner    if (UsedRegs[VRRegNo[i]])
663f7d2372b7407c7f8966df39a2b5a067c72bd6b9bChris Lattner      UsedRegMask |= 1 << (31-i);
664f7d2372b7407c7f8966df39a2b5a067c72bd6b9bChris Lattner
665402504b1ba250839102ba384be0210d248b6e3e8Chris Lattner  // Live in and live out values already must be in the mask, so don't bother
666402504b1ba250839102ba384be0210d248b6e3e8Chris Lattner  // marking them.
667402504b1ba250839102ba384be0210d248b6e3e8Chris Lattner  MachineFunction *MF = MI->getParent()->getParent();
668402504b1ba250839102ba384be0210d248b6e3e8Chris Lattner  for (MachineFunction::livein_iterator I =
669402504b1ba250839102ba384be0210d248b6e3e8Chris Lattner       MF->livein_begin(), E = MF->livein_end(); I != E; ++I) {
670402504b1ba250839102ba384be0210d248b6e3e8Chris Lattner    unsigned RegNo = PPCRegisterInfo::getRegisterNumbering(I->first);
671402504b1ba250839102ba384be0210d248b6e3e8Chris Lattner    if (VRRegNo[RegNo] == I->first)        // If this really is a vector reg.
672402504b1ba250839102ba384be0210d248b6e3e8Chris Lattner      UsedRegMask &= ~(1 << (31-RegNo));   // Doesn't need to be marked.
673402504b1ba250839102ba384be0210d248b6e3e8Chris Lattner  }
674402504b1ba250839102ba384be0210d248b6e3e8Chris Lattner  for (MachineFunction::liveout_iterator I =
675402504b1ba250839102ba384be0210d248b6e3e8Chris Lattner       MF->liveout_begin(), E = MF->liveout_end(); I != E; ++I) {
676402504b1ba250839102ba384be0210d248b6e3e8Chris Lattner    unsigned RegNo = PPCRegisterInfo::getRegisterNumbering(*I);
677402504b1ba250839102ba384be0210d248b6e3e8Chris Lattner    if (VRRegNo[RegNo] == *I)              // If this really is a vector reg.
678402504b1ba250839102ba384be0210d248b6e3e8Chris Lattner      UsedRegMask &= ~(1 << (31-RegNo));   // Doesn't need to be marked.
679402504b1ba250839102ba384be0210d248b6e3e8Chris Lattner  }
680402504b1ba250839102ba384be0210d248b6e3e8Chris Lattner
6811877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner  unsigned SrcReg = MI->getOperand(1).getReg();
6821877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner  unsigned DstReg = MI->getOperand(0).getReg();
6831877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner  // If no registers are used, turn this into a copy.
6841877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner  if (UsedRegMask == 0) {
685f9568d8700d5389799796262cde313bb5c7d588aChris Lattner    // Remove all VRSAVE code.
686f9568d8700d5389799796262cde313bb5c7d588aChris Lattner    RemoveVRSaveCode(MI);
687f9568d8700d5389799796262cde313bb5c7d588aChris Lattner    return;
6881877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner  } else if ((UsedRegMask & 0xFFFF) == UsedRegMask) {
689c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(*MI->getParent(), MI, TII.get(PPC::ORI), DstReg)
6901877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner        .addReg(SrcReg).addImm(UsedRegMask);
6911877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner  } else if ((UsedRegMask & 0xFFFF0000) == UsedRegMask) {
692c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(*MI->getParent(), MI, TII.get(PPC::ORIS), DstReg)
6931877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner        .addReg(SrcReg).addImm(UsedRegMask >> 16);
6941877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner  } else {
695c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(*MI->getParent(), MI, TII.get(PPC::ORIS), DstReg)
6961877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner       .addReg(SrcReg).addImm(UsedRegMask >> 16);
697c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(*MI->getParent(), MI, TII.get(PPC::ORI), DstReg)
6981877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner      .addReg(DstReg).addImm(UsedRegMask & 0xFFFF);
6991877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner  }
7001877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner
7011877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner  // Remove the old UPDATE_VRSAVE instruction.
702f9568d8700d5389799796262cde313bb5c7d588aChris Lattner  MI->eraseFromParent();
7031877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner}
7041877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner
7052f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey/// determineFrameLayout - Determine the size of the frame and maximum call
7062f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey/// frame size.
7072f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskeyvoid PPCRegisterInfo::determineFrameLayout(MachineFunction &MF) const {
7082f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  MachineFrameInfo *MFI = MF.getFrameInfo();
7092f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey
7102f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Get the number of bytes to allocate from the FrameInfo
7112f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  unsigned FrameSize = MFI->getStackSize();
7122f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey
7132f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Get the alignments provided by the target, and the maximum alignment
7142f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // (if any) of the fixed frame objects.
7152f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
7162f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  unsigned MaxAlign = MFI->getMaxAlignment();
7172f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  unsigned Align = std::max(TargetAlign, MaxAlign);
7182f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  assert(isPowerOf2_32(Align) && "Alignment is not power of 2");
7192f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  unsigned AlignMask = Align - 1;  //
7202f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey
7212f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // If we are a leaf function, and use up to 224 bytes of stack space,
7222f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // don't have a frame pointer, calls, or dynamic alloca then we do not need
7232f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // to adjust the stack pointer (we fit in the Red Zone).
7242f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  if (FrameSize <= 224 &&             // Fits in red zone.
7252ff5cdb16cea04f562402c2a33732840857a66e2Jim Laskey      !MFI->hasVarSizedObjects() &&   // No dynamic alloca.
7262f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey      !MFI->hasCalls() &&             // No calls.
7272f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey      MaxAlign <= TargetAlign) {      // No special alignment.
7282f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey    // No need for frame
7292f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey    MFI->setStackSize(0);
7302f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey    return;
7312f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  }
7322f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey
7332f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Get the maximum call frame size of all the calls.
7342f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  unsigned maxCallFrameSize = MFI->getMaxCallFrameSize();
7352f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey
7362f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Maximum call frame needs to be at least big enough for linkage and 8 args.
7372f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  unsigned minCallFrameSize =
7382f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey    PPCFrameInfo::getMinCallFrameSize(Subtarget.isPPC64());
7392f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  maxCallFrameSize = std::max(maxCallFrameSize, minCallFrameSize);
7402f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey
7412f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // If we have dynamic alloca then maxCallFrameSize needs to be aligned so
7422f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // that allocations will be aligned.
7432f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  if (MFI->hasVarSizedObjects())
7442f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey    maxCallFrameSize = (maxCallFrameSize + AlignMask) & ~AlignMask;
7452f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey
7462f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Update maximum call frame size.
7472f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  MFI->setMaxCallFrameSize(maxCallFrameSize);
7482f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey
7492f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Include call frame size in total.
7502f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  FrameSize += maxCallFrameSize;
7512f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey
7522f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Make sure the frame is aligned.
7532f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  FrameSize = (FrameSize + AlignMask) & ~AlignMask;
7542f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey
7552f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Update frame info.
7562f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  MFI->setStackSize(FrameSize);
7572f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey}
758f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman
75921e463b2bf864671a87ebe386cb100ef9349a540Nate Begemanvoid PPCRegisterInfo::emitPrologue(MachineFunction &MF) const {
760f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  MachineBasicBlock &MBB = MF.front();   // Prolog goes in entry BB
761f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  MachineBasicBlock::iterator MBBI = MBB.begin();
762f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  MachineFrameInfo *MFI = MF.getFrameInfo();
7634188699f80c233a20b6ddc61570a8a8c1804cb85Jim Laskey  MachineDebugInfo *DebugInfo = MFI->getMachineDebugInfo();
7644f91a4c497fb1032550b7f163004efc5fce1d7f1Chris Lattner
7654f91a4c497fb1032550b7f163004efc5fce1d7f1Chris Lattner  // Scan the prolog, looking for an UPDATE_VRSAVE instruction.  If we find it,
7664f91a4c497fb1032550b7f163004efc5fce1d7f1Chris Lattner  // process it.
7678aa777d5ea8e73e2edf79fd35fd6b5c4e9949ca7Chris Lattner  for (unsigned i = 0; MBBI != MBB.end(); ++i, ++MBBI) {
7681877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner    if (MBBI->getOpcode() == PPC::UPDATE_VRSAVE) {
769c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      HandleVRSaveUpdate(MBBI, MF.getUsedPhysregs(), TII);
7701877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner      break;
7711877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner    }
7721877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner  }
7731877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner
7741877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner  // Move MBBI back to the beginning of the function.
7751877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner  MBBI = MBB.begin();
7761877ec9b02511e111998596b9ba9c3a2275d6a92Chris Lattner
7772f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Work out frame sizes.
7782f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  determineFrameLayout(MF);
7792f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  unsigned FrameSize = MFI->getStackSize();
780ae232e7a1055033436370c0b3aecf054fa44d5e7Nate Begeman
7812f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Skip if a leaf routine.
7822f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  if (!FrameSize) return;
7832f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey
7842f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  int NegFrameSize = -FrameSize;
78551fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey
78651fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  // Get processor type.
78751fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  bool IsPPC64 = Subtarget.isPPC64();
78851fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  // Check if the link register (LR) has been used.
78951fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  bool UsesLR = MFI->hasCalls() || usesLR(MF);
7902f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Do we have a frame pointer for this function?
7912f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  bool HasFP = hasFP(MF);
79251fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey
79351fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  int LROffset = PPCFrameInfo::getReturnSaveOffset(IsPPC64);
79451fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64);
79551fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey
79651fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  if (IsPPC64) {
79751fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey    if (UsesLR)
79851fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey      BuildMI(MBB, MBBI, TII.get(PPC::MFLR8), PPC::X0);
79951fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey
80051fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey    if (HasFP)
80151fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey      BuildMI(MBB, MBBI, TII.get(PPC::STD))
80251fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey         .addReg(PPC::X31).addImm(FPOffset/4).addReg(PPC::X1);
80351fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey
80451fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey    if (UsesLR)
80551fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey      BuildMI(MBB, MBBI, TII.get(PPC::STD))
80651fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey         .addReg(PPC::X0).addImm(LROffset/4).addReg(PPC::X1);
80751fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  } else {
80851fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey    if (UsesLR)
80951fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey      BuildMI(MBB, MBBI, TII.get(PPC::MFLR), PPC::R0);
81051fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey
81151fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey    if (HasFP)
81251fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey      BuildMI(MBB, MBBI, TII.get(PPC::STW))
81351fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey        .addReg(PPC::R31).addImm(FPOffset).addReg(PPC::R1);
814f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman
81551fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey    if (UsesLR)
816c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      BuildMI(MBB, MBBI, TII.get(PPC::STW))
81751fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey        .addReg(PPC::R0).addImm(LROffset).addReg(PPC::R1);
81854eed36da595f09c46a46b2b0b15757ea486b4c1Nate Begeman  }
8192f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey
8202f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Get stack alignments.
8212f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
8222f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  unsigned MaxAlign = MFI->getMaxAlignment();
823f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman
8242f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // Adjust stack pointer: r1 += NegFrameSize.
825030514cd96e9b8bb08fd9585d890bd7a5f0dbb77Nate Begeman  // If there is a preferred stack alignment, align R1 now
82651fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  if (!IsPPC64) {
827a94a203f346e65d40c4c3fe478c5d8d7a2ff5df6Chris Lattner    // PPC32.
828a94a203f346e65d40c4c3fe478c5d8d7a2ff5df6Chris Lattner    if (MaxAlign > TargetAlign) {
8292f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey      assert(isPowerOf2_32(MaxAlign)&&isInt16(MaxAlign)&&"Invalid alignment!");
8302f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey      assert(isInt16(NegFrameSize) && "Unhandled stack size and alignment!");
831c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      BuildMI(MBB, MBBI, TII.get(PPC::RLWINM), PPC::R0)
832a94a203f346e65d40c4c3fe478c5d8d7a2ff5df6Chris Lattner        .addReg(PPC::R1).addImm(0).addImm(32-Log2_32(MaxAlign)).addImm(31);
833c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      BuildMI(MBB, MBBI, TII.get(PPC::SUBFIC) ,PPC::R0).addReg(PPC::R0)
8342f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey        .addImm(NegFrameSize);
835c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      BuildMI(MBB, MBBI, TII.get(PPC::STWUX))
836a94a203f346e65d40c4c3fe478c5d8d7a2ff5df6Chris Lattner        .addReg(PPC::R1).addReg(PPC::R1).addReg(PPC::R0);
8372f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey    } else if (isInt16(NegFrameSize)) {
838c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      BuildMI(MBB, MBBI, TII.get(PPC::STWU),
8392f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey              PPC::R1).addReg(PPC::R1).addImm(NegFrameSize).addReg(PPC::R1);
840a94a203f346e65d40c4c3fe478c5d8d7a2ff5df6Chris Lattner    } else {
841c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      BuildMI(MBB, MBBI, TII.get(PPC::LIS), PPC::R0).addImm(NegFrameSize >> 16);
842c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      BuildMI(MBB, MBBI, TII.get(PPC::ORI), PPC::R0).addReg(PPC::R0)
8432f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey        .addImm(NegFrameSize & 0xFFFF);
844c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      BuildMI(MBB, MBBI, TII.get(PPC::STWUX)).addReg(PPC::R1).addReg(PPC::R1)
845a94a203f346e65d40c4c3fe478c5d8d7a2ff5df6Chris Lattner        .addReg(PPC::R0);
846a94a203f346e65d40c4c3fe478c5d8d7a2ff5df6Chris Lattner    }
847a94a203f346e65d40c4c3fe478c5d8d7a2ff5df6Chris Lattner  } else {    // PPC64.
848a94a203f346e65d40c4c3fe478c5d8d7a2ff5df6Chris Lattner    if (MaxAlign > TargetAlign) {
8492f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey      assert(isPowerOf2_32(MaxAlign)&&isInt16(MaxAlign)&&"Invalid alignment!");
8502f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey      assert(isInt16(NegFrameSize) && "Unhandled stack size and alignment!");
851c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      BuildMI(MBB, MBBI, TII.get(PPC::RLDICL), PPC::X0)
852a94a203f346e65d40c4c3fe478c5d8d7a2ff5df6Chris Lattner        .addReg(PPC::X1).addImm(0).addImm(64-Log2_32(MaxAlign));
853c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      BuildMI(MBB, MBBI, TII.get(PPC::SUBFIC8), PPC::X0).addReg(PPC::X0)
8542f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey        .addImm(NegFrameSize);
855c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      BuildMI(MBB, MBBI, TII.get(PPC::STDUX))
856a94a203f346e65d40c4c3fe478c5d8d7a2ff5df6Chris Lattner        .addReg(PPC::X1).addReg(PPC::X1).addReg(PPC::X0);
8572ff5cdb16cea04f562402c2a33732840857a66e2Jim Laskey    } else if (isInt16(NegFrameSize)) {
858c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      BuildMI(MBB, MBBI, TII.get(PPC::STDU), PPC::X1)
8592f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey             .addReg(PPC::X1).addImm(NegFrameSize/4).addReg(PPC::X1);
860a94a203f346e65d40c4c3fe478c5d8d7a2ff5df6Chris Lattner    } else {
861c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      BuildMI(MBB, MBBI, TII.get(PPC::LIS8), PPC::X0).addImm(NegFrameSize >>16);
862c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      BuildMI(MBB, MBBI, TII.get(PPC::ORI8), PPC::X0).addReg(PPC::X0)
8632f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey        .addImm(NegFrameSize & 0xFFFF);
864c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      BuildMI(MBB, MBBI, TII.get(PPC::STDUX)).addReg(PPC::X1).addReg(PPC::X1)
865a94a203f346e65d40c4c3fe478c5d8d7a2ff5df6Chris Lattner        .addReg(PPC::X0);
866a94a203f346e65d40c4c3fe478c5d8d7a2ff5df6Chris Lattner    }
867f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  }
868ae232e7a1055033436370c0b3aecf054fa44d5e7Nate Begeman
86952fa2449c9c1c8f8373faccb8968588211101e68Jim Laskey  if (DebugInfo && DebugInfo->hasInfo()) {
8704188699f80c233a20b6ddc61570a8a8c1804cb85Jim Laskey    std::vector<MachineMove *> &Moves = DebugInfo->getFrameMoves();
8714188699f80c233a20b6ddc61570a8a8c1804cb85Jim Laskey    unsigned LabelID = DebugInfo->NextLabelID();
8724188699f80c233a20b6ddc61570a8a8c1804cb85Jim Laskey
8734c2c9031acd1314440cdd0952182fa39b4efe90dJim Laskey    // Mark effective beginning of when frame pointer becomes valid.
874c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng    BuildMI(MBB, MBBI, TII.get(PPC::DWARF_LABEL)).addImm(LabelID);
8754c2c9031acd1314440cdd0952182fa39b4efe90dJim Laskey
876ce50a165c784d71abf1b2f981be18f867787d972Jim Laskey    // Show update of SP.
877ce50a165c784d71abf1b2f981be18f867787d972Jim Laskey    MachineLocation SPDst(MachineLocation::VirtualFP);
8782f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey    MachineLocation SPSrc(MachineLocation::VirtualFP, NegFrameSize);
879ce50a165c784d71abf1b2f981be18f867787d972Jim Laskey    Moves.push_back(new MachineMove(LabelID, SPDst, SPSrc));
880ce50a165c784d71abf1b2f981be18f867787d972Jim Laskey
881ce50a165c784d71abf1b2f981be18f867787d972Jim Laskey    // Add callee saved registers to move list.
882ce50a165c784d71abf1b2f981be18f867787d972Jim Laskey    const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
883ce50a165c784d71abf1b2f981be18f867787d972Jim Laskey    for (unsigned I = 0, E = CSI.size(); I != E; ++I) {
884ce50a165c784d71abf1b2f981be18f867787d972Jim Laskey      MachineLocation CSDst(MachineLocation::VirtualFP,
885ce50a165c784d71abf1b2f981be18f867787d972Jim Laskey                            MFI->getObjectOffset(CSI[I].getFrameIdx()));
886ce50a165c784d71abf1b2f981be18f867787d972Jim Laskey      MachineLocation CSSrc(CSI[I].getReg());
887ce50a165c784d71abf1b2f981be18f867787d972Jim Laskey      Moves.push_back(new MachineMove(LabelID, CSDst, CSSrc));
888ce50a165c784d71abf1b2f981be18f867787d972Jim Laskey    }
8894188699f80c233a20b6ddc61570a8a8c1804cb85Jim Laskey  }
8902f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey
8912f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  // If there is a frame pointer, copy R1 into R31
8924f91a4c497fb1032550b7f163004efc5fce1d7f1Chris Lattner  if (HasFP) {
89351fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey    if (!IsPPC64) {
894c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      BuildMI(MBB, MBBI, TII.get(PPC::OR), PPC::R31).addReg(PPC::R1)
895c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng        .addReg(PPC::R1);
896a94a203f346e65d40c4c3fe478c5d8d7a2ff5df6Chris Lattner    } else {
897c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng      BuildMI(MBB, MBBI, TII.get(PPC::OR8), PPC::X31).addReg(PPC::X1)
898c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng        .addReg(PPC::X1);
899a94a203f346e65d40c4c3fe478c5d8d7a2ff5df6Chris Lattner    }
900f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  }
901f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman}
902f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman
90321e463b2bf864671a87ebe386cb100ef9349a540Nate Begemanvoid PPCRegisterInfo::emitEpilogue(MachineFunction &MF,
90421e463b2bf864671a87ebe386cb100ef9349a540Nate Begeman                                   MachineBasicBlock &MBB) const {
905f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  MachineBasicBlock::iterator MBBI = prior(MBB.end());
9066da8d99f70826552b3a4e7bd5d1376881574b4b1Evan Cheng  assert(MBBI->getOpcode() == PPC::BLR &&
907f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman         "Can only insert epilog into returning blocks");
908b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman
909030514cd96e9b8bb08fd9585d890bd7a5f0dbb77Nate Begeman  // Get alignment info so we know how to restore r1
910030514cd96e9b8bb08fd9585d890bd7a5f0dbb77Nate Begeman  const MachineFrameInfo *MFI = MF.getFrameInfo();
911030514cd96e9b8bb08fd9585d890bd7a5f0dbb77Nate Begeman  unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
9122f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  unsigned MaxAlign = MFI->getMaxAlignment();
913030514cd96e9b8bb08fd9585d890bd7a5f0dbb77Nate Begeman
91464da172b1435d132ce867dcd5c652577664b55a3Chris Lattner  // Get the number of bytes allocated from the FrameInfo.
9152f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey  unsigned FrameSize = MFI->getStackSize();
916f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman
91751fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  if (!FrameSize) return;
91851fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey
91951fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  // Get processor type.
92051fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  bool IsPPC64 = Subtarget.isPPC64();
92151fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  // Check if the link register (LR) has been used.
92251fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  bool UsesLR = MFI->hasCalls() || usesLR(MF);
92351fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  // Do we have a frame pointer for this function?
92451fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  bool HasFP = hasFP(MF);
92551fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey
92651fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  // The loaded (or persistent) stack pointer value is offset by the 'stwu'
92751fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  // on entry to the function.  Add this offset back now.
92851fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  if (!Subtarget.isPPC64()) {
92951fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey    if (isInt16(FrameSize) && TargetAlign >= MaxAlign &&
93051fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey          !MFI->hasVarSizedObjects()) {
93151fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey        BuildMI(MBB, MBBI, TII.get(PPC::ADDI), PPC::R1)
93251fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey            .addReg(PPC::R1).addImm(FrameSize);
93364da172b1435d132ce867dcd5c652577664b55a3Chris Lattner    } else {
93451fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey      BuildMI(MBB, MBBI, TII.get(PPC::LWZ),PPC::R1).addImm(0).addReg(PPC::R1);
935f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman    }
93651fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  } else {
93751fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey    if (isInt16(FrameSize) && TargetAlign >= MaxAlign &&
93851fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey          !MFI->hasVarSizedObjects()) {
93951fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey      BuildMI(MBB, MBBI, TII.get(PPC::ADDI8), PPC::X1)
94051fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey         .addReg(PPC::X1).addImm(FrameSize);
94151fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey    } else {
94251fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey      BuildMI(MBB, MBBI, TII.get(PPC::LD), PPC::X1).addImm(0).addReg(PPC::X1);
9432f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey    }
94451fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  }
94551fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey
94651fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  int LROffset = PPCFrameInfo::getReturnSaveOffset(IsPPC64);
94751fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64);
94851fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey
94951fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  if (IsPPC64) {
95051fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey    if (UsesLR)
95151fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey      BuildMI(MBB, MBBI, TII.get(PPC::LD), PPC::X0)
95251fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey        .addImm(LROffset/4).addReg(PPC::X1);
95351fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey
95451fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey    if (HasFP)
95551fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey      BuildMI(MBB, MBBI, TII.get(PPC::LD), PPC::X31)
95651fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey        .addImm(FPOffset/4).addReg(PPC::X1);
95751fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey
95851fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey    if (UsesLR)
95951fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey      BuildMI(MBB, MBBI, TII.get(PPC::MTLR8)).addReg(PPC::X0);
96051fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey  } else {
96151fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey    if (UsesLR)
96251fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey      BuildMI(MBB, MBBI, TII.get(PPC::LWZ), PPC::R0)
96351fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey          .addImm(LROffset).addReg(PPC::R1);
96451fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey
96551fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey    if (HasFP)
96651fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey      BuildMI(MBB, MBBI, TII.get(PPC::LWZ), PPC::R31)
96751fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey          .addImm(FPOffset).addReg(PPC::R1);
96851fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey
96951fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey    if (UsesLR)
97051fe9d9aa432cbde6497cad4ea5c8f0276c67b82Jim Laskey      BuildMI(MBB, MBBI, TII.get(PPC::MTLR)).addReg(PPC::R0);
971f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman  }
972f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman}
973f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman
9744188699f80c233a20b6ddc61570a8a8c1804cb85Jim Laskeyunsigned PPCRegisterInfo::getRARegister() const {
9756a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner  return !Subtarget.isPPC64() ? PPC::LR : PPC::LR8;
9766a5339ba656805a9cd3bf7d884f99bb87ec84e98Chris Lattner
9774188699f80c233a20b6ddc61570a8a8c1804cb85Jim Laskey}
9784188699f80c233a20b6ddc61570a8a8c1804cb85Jim Laskey
979a99791886d5d4af2b900cd8cc1c9ed1677b6f0f4Jim Laskeyunsigned PPCRegisterInfo::getFrameRegister(MachineFunction &MF) const {
980a94a203f346e65d40c4c3fe478c5d8d7a2ff5df6Chris Lattner  if (!Subtarget.isPPC64())
981a94a203f346e65d40c4c3fe478c5d8d7a2ff5df6Chris Lattner    return hasFP(MF) ? PPC::R31 : PPC::R1;
982a94a203f346e65d40c4c3fe478c5d8d7a2ff5df6Chris Lattner  else
983a94a203f346e65d40c4c3fe478c5d8d7a2ff5df6Chris Lattner    return hasFP(MF) ? PPC::X31 : PPC::X1;
9844188699f80c233a20b6ddc61570a8a8c1804cb85Jim Laskey}
9854188699f80c233a20b6ddc61570a8a8c1804cb85Jim Laskey
9864188699f80c233a20b6ddc61570a8a8c1804cb85Jim Laskeyvoid PPCRegisterInfo::getInitialFrameState(std::vector<MachineMove *> &Moves)
9874188699f80c233a20b6ddc61570a8a8c1804cb85Jim Laskey                                                                         const {
9884c2c9031acd1314440cdd0952182fa39b4efe90dJim Laskey  // Initial state of the frame pointer is R1.
9894188699f80c233a20b6ddc61570a8a8c1804cb85Jim Laskey  MachineLocation Dst(MachineLocation::VirtualFP);
9904188699f80c233a20b6ddc61570a8a8c1804cb85Jim Laskey  MachineLocation Src(PPC::R1, 0);
9914188699f80c233a20b6ddc61570a8a8c1804cb85Jim Laskey  Moves.push_back(new MachineMove(0, Dst, Src));
992f1d78e83356a412e525c30ac90dabf090a8cfc99Jim Laskey}
993f1d78e83356a412e525c30ac90dabf090a8cfc99Jim Laskey
9944c7b43b43fdf943c7298718e15ab5d6dfe345be7Chris Lattner#include "PPCGenRegisterInfo.inc"
995f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman
996