ARMBaseRegisterInfo.cpp revision 8a8d479214745c82ef00f08d4e4f1c173b5f9ce2
12cfd52c507bd5790457a171eb9bcb39019cc6860Chris Lattner//===- ARMBaseRegisterInfo.cpp - ARM Register Information -------*- C++ -*-===// 2c140c4803dc3e10e08138670829bc0494986abe9David Goodwin// 3c140c4803dc3e10e08138670829bc0494986abe9David Goodwin// The LLVM Compiler Infrastructure 4c140c4803dc3e10e08138670829bc0494986abe9David Goodwin// 5c140c4803dc3e10e08138670829bc0494986abe9David Goodwin// This file is distributed under the University of Illinois Open Source 6c140c4803dc3e10e08138670829bc0494986abe9David Goodwin// License. See LICENSE.TXT for details. 7c140c4803dc3e10e08138670829bc0494986abe9David Goodwin// 8c140c4803dc3e10e08138670829bc0494986abe9David Goodwin//===----------------------------------------------------------------------===// 9c140c4803dc3e10e08138670829bc0494986abe9David Goodwin// 10c140c4803dc3e10e08138670829bc0494986abe9David Goodwin// This file contains the base ARM implementation of TargetRegisterInfo class. 11c140c4803dc3e10e08138670829bc0494986abe9David Goodwin// 12c140c4803dc3e10e08138670829bc0494986abe9David Goodwin//===----------------------------------------------------------------------===// 13c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 14c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "ARM.h" 15db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin#include "ARMBaseInstrInfo.h" 16c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "ARMBaseRegisterInfo.h" 1716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov#include "ARMFrameLowering.h" 18c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "ARMInstrInfo.h" 19c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "ARMMachineFunctionInfo.h" 20c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "ARMSubtarget.h" 21ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h" 22c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/Constants.h" 23c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/DerivedTypes.h" 249adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Anderson#include "llvm/Function.h" 259adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Anderson#include "llvm/LLVMContext.h" 26c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/CodeGen/MachineConstantPool.h" 27c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/CodeGen/MachineFrameInfo.h" 28c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/CodeGen/MachineFunction.h" 29c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/CodeGen/MachineInstrBuilder.h" 30c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/CodeGen/MachineRegisterInfo.h" 31c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/CodeGen/RegisterScavenging.h" 323dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach#include "llvm/Support/Debug.h" 33ab7c09b6b6f4516a631fd6788918c237c83939afTorok Edwin#include "llvm/Support/ErrorHandling.h" 34dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/raw_ostream.h" 3516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov#include "llvm/Target/TargetFrameLowering.h" 36c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/Target/TargetMachine.h" 37c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/Target/TargetOptions.h" 38c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/ADT/BitVector.h" 39c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/ADT/SmallVector.h" 4018ed9c9a2bd7f1f56129495b499264c58b5cc4f4Jim Grosbach#include "llvm/Support/CommandLine.h" 4173f50d9bc3bd46cc0abeba9bb0d46977ba1aea42Evan Cheng 4273f50d9bc3bd46cc0abeba9bb0d46977ba1aea42Evan Cheng#define GET_REGINFO_TARGET_DESC 43a347f85dbeee37a7f2bb68df1a7d4cdfbb7b576dEvan Cheng#include "ARMGenRegisterInfo.inc" 44c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 451b4886dd00578038c0ca70b3bab97382b89def26Evan Chengusing namespace llvm; 461b4886dd00578038c0ca70b3bab97382b89def26Evan Cheng 47a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbachstatic cl::opt<bool> 483197380143cdc18837722129ac888528b9fbfc2bJim GrosbachForceAllBaseRegAlloc("arm-force-base-reg-alloc", cl::Hidden, cl::init(false), 49cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach cl::desc("Force use of virtual base registers for stack load/store")); 50a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbachstatic cl::opt<bool> 51ae47c6d69e2e34bc558a302586cbc3f27a6d7334Jim GrosbachEnableLocalStackAlloc("enable-local-stack-alloc", cl::init(true), cl::Hidden, 52a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbach cl::desc("Enable pre-regalloc stack frame index allocation")); 5365482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbachstatic cl::opt<bool> 54d0bd76b0fb27830f18e15e3d73f2e383ff1c59f1Jim GrosbachEnableBasePointer("arm-use-base-pointer", cl::Hidden, cl::init(true), 5565482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach cl::desc("Enable use of a base pointer for complex stack frames")); 5665482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach 57db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwinARMBaseRegisterInfo::ARMBaseRegisterInfo(const ARMBaseInstrInfo &tii, 58c140c4803dc3e10e08138670829bc0494986abe9David Goodwin const ARMSubtarget &sti) 590e6a052331f674dd70e28af41f654a7874405eabEvan Cheng : ARMGenRegisterInfo(ARM::LR), TII(tii), STI(sti), 6065482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach FramePtr((STI.isTargetDarwin() || STI.isThumb()) ? ARM::R7 : ARM::R11), 6165482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach BasePtr(ARM::R6) { 62c140c4803dc3e10e08138670829bc0494986abe9David Goodwin} 63c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 64c140c4803dc3e10e08138670829bc0494986abe9David Goodwinconst unsigned* 65c140c4803dc3e10e08138670829bc0494986abe9David GoodwinARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 66c140c4803dc3e10e08138670829bc0494986abe9David Goodwin static const unsigned CalleeSavedRegs[] = { 67c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::LR, ARM::R11, ARM::R10, ARM::R9, ARM::R8, 68c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R7, ARM::R6, ARM::R5, ARM::R4, 69c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 70c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::D15, ARM::D14, ARM::D13, ARM::D12, 71c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::D11, ARM::D10, ARM::D9, ARM::D8, 72c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 0 73c140c4803dc3e10e08138670829bc0494986abe9David Goodwin }; 74c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 75c140c4803dc3e10e08138670829bc0494986abe9David Goodwin static const unsigned DarwinCalleeSavedRegs[] = { 76c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // Darwin ABI deviates from ARM standard ABI. R9 is not a callee-saved 77c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // register. 78ab3d00e5350fd4c097e2a5b077da7584692029a7Jim Grosbach ARM::LR, ARM::R7, ARM::R6, ARM::R5, ARM::R4, 79ab3d00e5350fd4c097e2a5b077da7584692029a7Jim Grosbach ARM::R11, ARM::R10, ARM::R8, 80c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 81c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::D15, ARM::D14, ARM::D13, ARM::D12, 82c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::D11, ARM::D10, ARM::D9, ARM::D8, 83c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 0 84c140c4803dc3e10e08138670829bc0494986abe9David Goodwin }; 85c140c4803dc3e10e08138670829bc0494986abe9David Goodwin return STI.isTargetDarwin() ? DarwinCalleeSavedRegs : CalleeSavedRegs; 86c140c4803dc3e10e08138670829bc0494986abe9David Goodwin} 87c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 889631864688c593711f82bb8d21f8b724c628d786Jim GrosbachBitVector ARMBaseRegisterInfo:: 899631864688c593711f82bb8d21f8b724c628d786Jim GrosbachgetReservedRegs(const MachineFunction &MF) const { 9016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 91d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 927a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // FIXME: avoid re-calculating this every time. 93c140c4803dc3e10e08138670829bc0494986abe9David Goodwin BitVector Reserved(getNumRegs()); 94c140c4803dc3e10e08138670829bc0494986abe9David Goodwin Reserved.set(ARM::SP); 95c140c4803dc3e10e08138670829bc0494986abe9David Goodwin Reserved.set(ARM::PC); 96d1fb583128c6682bb8a7c74eafa810a9270cc8dfNate Begeman Reserved.set(ARM::FPSCR); 97d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (TFI->hasFP(MF)) 98c140c4803dc3e10e08138670829bc0494986abe9David Goodwin Reserved.set(FramePtr); 9965482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach if (hasBasePointer(MF)) 10065482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach Reserved.set(BasePtr); 101c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // Some targets reserve R9. 102c140c4803dc3e10e08138670829bc0494986abe9David Goodwin if (STI.isR9Reserved()) 103c140c4803dc3e10e08138670829bc0494986abe9David Goodwin Reserved.set(ARM::R9); 1043b6434e360315849a65b1ac85e16d160131a77a4Jakob Stoklund Olesen // Reserve D16-D31 if the subtarget doesn't support them. 1053b6434e360315849a65b1ac85e16d160131a77a4Jakob Stoklund Olesen if (!STI.hasVFP3() || STI.hasD16()) { 1063b6434e360315849a65b1ac85e16d160131a77a4Jakob Stoklund Olesen assert(ARM::D31 == ARM::D16 + 15); 1073b6434e360315849a65b1ac85e16d160131a77a4Jakob Stoklund Olesen for (unsigned i = 0; i != 16; ++i) 1083b6434e360315849a65b1ac85e16d160131a77a4Jakob Stoklund Olesen Reserved.set(ARM::D16 + i); 1093b6434e360315849a65b1ac85e16d160131a77a4Jakob Stoklund Olesen } 110c140c4803dc3e10e08138670829bc0494986abe9David Goodwin return Reserved; 111c140c4803dc3e10e08138670829bc0494986abe9David Goodwin} 112c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 1132cfd52c507bd5790457a171eb9bcb39019cc6860Chris Lattnerbool ARMBaseRegisterInfo::isReservedReg(const MachineFunction &MF, 1142cfd52c507bd5790457a171eb9bcb39019cc6860Chris Lattner unsigned Reg) const { 11516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 116d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 117c140c4803dc3e10e08138670829bc0494986abe9David Goodwin switch (Reg) { 118c140c4803dc3e10e08138670829bc0494986abe9David Goodwin default: break; 119c140c4803dc3e10e08138670829bc0494986abe9David Goodwin case ARM::SP: 120c140c4803dc3e10e08138670829bc0494986abe9David Goodwin case ARM::PC: 121c140c4803dc3e10e08138670829bc0494986abe9David Goodwin return true; 12265482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach case ARM::R6: 12365482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach if (hasBasePointer(MF)) 12465482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach return true; 12565482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach break; 126c140c4803dc3e10e08138670829bc0494986abe9David Goodwin case ARM::R7: 127c140c4803dc3e10e08138670829bc0494986abe9David Goodwin case ARM::R11: 128d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (FramePtr == Reg && TFI->hasFP(MF)) 129c140c4803dc3e10e08138670829bc0494986abe9David Goodwin return true; 130c140c4803dc3e10e08138670829bc0494986abe9David Goodwin break; 131c140c4803dc3e10e08138670829bc0494986abe9David Goodwin case ARM::R9: 132c140c4803dc3e10e08138670829bc0494986abe9David Goodwin return STI.isR9Reserved(); 133c140c4803dc3e10e08138670829bc0494986abe9David Goodwin } 134c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 135c140c4803dc3e10e08138670829bc0494986abe9David Goodwin return false; 136c140c4803dc3e10e08138670829bc0494986abe9David Goodwin} 137c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 1382cfd52c507bd5790457a171eb9bcb39019cc6860Chris Lattnerconst TargetRegisterClass * 1394f54c1293af174a8002db20faf7b4f82ba4e8514Evan ChengARMBaseRegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A, 1404f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng const TargetRegisterClass *B, 1414f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng unsigned SubIdx) const { 1424f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng switch (SubIdx) { 1434f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng default: return 0; 144e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen case ARM::ssub_0: 145e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen case ARM::ssub_1: 146e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen case ARM::ssub_2: 147e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen case ARM::ssub_3: { 1484f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng // S sub-registers. 1494f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng if (A->getSize() == 8) { 150ba908640b3e0c1218748776e244d4b7234451155Evan Cheng if (B == &ARM::SPR_8RegClass) 151ba908640b3e0c1218748776e244d4b7234451155Evan Cheng return &ARM::DPR_8RegClass; 152ba908640b3e0c1218748776e244d4b7234451155Evan Cheng assert(B == &ARM::SPRRegClass && "Expecting SPR register class!"); 1534f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng if (A == &ARM::DPR_8RegClass) 1544f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng return A; 1554f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng return &ARM::DPR_VFP2RegClass; 1564f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng } 1574f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng 158b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng if (A->getSize() == 16) { 159b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng if (B == &ARM::SPR_8RegClass) 160b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng return &ARM::QPR_8RegClass; 161b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng return &ARM::QPR_VFP2RegClass; 162b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng } 163b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng 16422c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng if (A->getSize() == 32) { 16522c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng if (B == &ARM::SPR_8RegClass) 16622c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng return 0; // Do not allow coalescing! 16722c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng return &ARM::QQPR_VFP2RegClass; 16822c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng } 16922c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng 17022c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng assert(A->getSize() == 64 && "Expecting a QQQQ register class!"); 17122c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng return 0; // Do not allow coalescing! 172b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng } 173e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen case ARM::dsub_0: 174e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen case ARM::dsub_1: 175e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen case ARM::dsub_2: 176e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen case ARM::dsub_3: { 1774f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng // D sub-registers. 178b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng if (A->getSize() == 16) { 179b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng if (B == &ARM::DPR_VFP2RegClass) 180b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng return &ARM::QPR_VFP2RegClass; 181b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng if (B == &ARM::DPR_8RegClass) 18222c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng return 0; // Do not allow coalescing! 183b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng return A; 184b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng } 185b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng 18622c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng if (A->getSize() == 32) { 18722c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng if (B == &ARM::DPR_VFP2RegClass) 18822c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng return &ARM::QQPR_VFP2RegClass; 18922c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng if (B == &ARM::DPR_8RegClass) 19022c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng return 0; // Do not allow coalescing! 19122c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng return A; 19222c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng } 19322c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng 19422c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng assert(A->getSize() == 64 && "Expecting a QQQQ register class!"); 19522c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng if (B != &ARM::DPRRegClass) 19622c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng return 0; // Do not allow coalescing! 1974f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng return A; 1984f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng } 199e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen case ARM::dsub_4: 200e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen case ARM::dsub_5: 201e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen case ARM::dsub_6: 202e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen case ARM::dsub_7: { 20322c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng // D sub-registers of QQQQ registers. 20422c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng if (A->getSize() == 64 && B == &ARM::DPRRegClass) 20522c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng return A; 20622c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng return 0; // Do not allow coalescing! 20722c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng } 20822c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng 209e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen case ARM::qsub_0: 210e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen case ARM::qsub_1: { 211b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng // Q sub-registers. 21222c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng if (A->getSize() == 32) { 21322c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng if (B == &ARM::QPR_VFP2RegClass) 21422c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng return &ARM::QQPR_VFP2RegClass; 21522c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng if (B == &ARM::QPR_8RegClass) 21622c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng return 0; // Do not allow coalescing! 21722c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng return A; 21822c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng } 21922c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng 22022c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng assert(A->getSize() == 64 && "Expecting a QQQQ register class!"); 22122c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng if (B == &ARM::QPRRegClass) 22222c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng return A; 22322c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng return 0; // Do not allow coalescing! 22422c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng } 225e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen case ARM::qsub_2: 226e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen case ARM::qsub_3: { 22722c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng // Q sub-registers of QQQQ registers. 22822c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng if (A->getSize() == 64 && B == &ARM::QPRRegClass) 22922c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng return A; 23022c687b6421d9cc03351ddb0c7fd3d45382bc01aEvan Cheng return 0; // Do not allow coalescing! 231b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng } 232b63387afc6b10e88631d1ef232c41ab6c18c8581Evan Cheng } 2334f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng return 0; 2344f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng} 2354f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng 236b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Chengbool 23791a74da036d3a9442953ae1de3e797a50da4ccf0Bob WilsonARMBaseRegisterInfo::canCombineSubRegIndices(const TargetRegisterClass *RC, 238b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng SmallVectorImpl<unsigned> &SubIndices, 239b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng unsigned &NewSubIdx) const { 240b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng 241b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng unsigned Size = RC->getSize() * 8; 242b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng if (Size < 6) 243b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng return 0; 244b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng 245b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng NewSubIdx = 0; // Whole register. 246b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng unsigned NumRegs = SubIndices.size(); 247b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng if (NumRegs == 8) { 248b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng // 8 D registers -> 1 QQQQ register. 249b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng return (Size == 512 && 250558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen SubIndices[0] == ARM::dsub_0 && 251558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen SubIndices[1] == ARM::dsub_1 && 252558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen SubIndices[2] == ARM::dsub_2 && 253558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen SubIndices[3] == ARM::dsub_3 && 254558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen SubIndices[4] == ARM::dsub_4 && 255558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen SubIndices[5] == ARM::dsub_5 && 256558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen SubIndices[6] == ARM::dsub_6 && 257558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen SubIndices[7] == ARM::dsub_7); 258b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng } else if (NumRegs == 4) { 259558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen if (SubIndices[0] == ARM::qsub_0) { 260b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng // 4 Q registers -> 1 QQQQ register. 261b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng return (Size == 512 && 262558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen SubIndices[1] == ARM::qsub_1 && 263558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen SubIndices[2] == ARM::qsub_2 && 264558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen SubIndices[3] == ARM::qsub_3); 265558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen } else if (SubIndices[0] == ARM::dsub_0) { 266b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng // 4 D registers -> 1 QQ register. 267b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng if (Size >= 256 && 268558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen SubIndices[1] == ARM::dsub_1 && 269558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen SubIndices[2] == ARM::dsub_2 && 270558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen SubIndices[3] == ARM::dsub_3) { 271b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng if (Size == 512) 272558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen NewSubIdx = ARM::qqsub_0; 273b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng return true; 274b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng } 275558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen } else if (SubIndices[0] == ARM::dsub_4) { 276b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng // 4 D registers -> 1 QQ register (2nd). 277b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng if (Size == 512 && 278558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen SubIndices[1] == ARM::dsub_5 && 279558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen SubIndices[2] == ARM::dsub_6 && 280558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen SubIndices[3] == ARM::dsub_7) { 281558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen NewSubIdx = ARM::qqsub_1; 282b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng return true; 283b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng } 284558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen } else if (SubIndices[0] == ARM::ssub_0) { 285b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng // 4 S registers -> 1 Q register. 286b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng if (Size >= 128 && 287558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen SubIndices[1] == ARM::ssub_1 && 288558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen SubIndices[2] == ARM::ssub_2 && 289558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen SubIndices[3] == ARM::ssub_3) { 290b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng if (Size >= 256) 291558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen NewSubIdx = ARM::qsub_0; 292b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng return true; 293b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng } 294b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng } 295b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng } else if (NumRegs == 2) { 296558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen if (SubIndices[0] == ARM::qsub_0) { 297b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng // 2 Q registers -> 1 QQ register. 298558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen if (Size >= 256 && SubIndices[1] == ARM::qsub_1) { 299b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng if (Size == 512) 300558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen NewSubIdx = ARM::qqsub_0; 301b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng return true; 302b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng } 303558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen } else if (SubIndices[0] == ARM::qsub_2) { 304b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng // 2 Q registers -> 1 QQ register (2nd). 305558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen if (Size == 512 && SubIndices[1] == ARM::qsub_3) { 306558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen NewSubIdx = ARM::qqsub_1; 307b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng return true; 308b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng } 309558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen } else if (SubIndices[0] == ARM::dsub_0) { 310b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng // 2 D registers -> 1 Q register. 311558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen if (Size >= 128 && SubIndices[1] == ARM::dsub_1) { 312b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng if (Size >= 256) 313558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen NewSubIdx = ARM::qsub_0; 314b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng return true; 315b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng } 316558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen } else if (SubIndices[0] == ARM::dsub_2) { 317b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng // 2 D registers -> 1 Q register (2nd). 318558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen if (Size >= 256 && SubIndices[1] == ARM::dsub_3) { 319558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen NewSubIdx = ARM::qsub_1; 320b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng return true; 321b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng } 322558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen } else if (SubIndices[0] == ARM::dsub_4) { 323b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng // 2 D registers -> 1 Q register (3rd). 324558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen if (Size == 512 && SubIndices[1] == ARM::dsub_5) { 325558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen NewSubIdx = ARM::qsub_2; 326b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng return true; 327b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng } 328558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen } else if (SubIndices[0] == ARM::dsub_6) { 329b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng // 2 D registers -> 1 Q register (3rd). 330558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen if (Size == 512 && SubIndices[1] == ARM::dsub_7) { 331558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen NewSubIdx = ARM::qsub_3; 332b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng return true; 333b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng } 334558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen } else if (SubIndices[0] == ARM::ssub_0) { 335b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng // 2 S registers -> 1 D register. 336558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen if (SubIndices[1] == ARM::ssub_1) { 337b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng if (Size >= 128) 338558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen NewSubIdx = ARM::dsub_0; 339b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng return true; 340b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng } 341558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen } else if (SubIndices[0] == ARM::ssub_2) { 342b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng // 2 S registers -> 1 D register (2nd). 343558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen if (Size >= 128 && SubIndices[1] == ARM::ssub_3) { 344558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen NewSubIdx = ARM::dsub_1; 345b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng return true; 346b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng } 347b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng } 348b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng } 349b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng return false; 350b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng} 351b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng 352c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesenconst TargetRegisterClass* 353c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund OlesenARMBaseRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC) 354c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen const { 355c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen const TargetRegisterClass *Super = RC; 356c8e2bb68bbc4a71cc10084c8f89565b9f05e12efJakob Stoklund Olesen TargetRegisterClass::sc_iterator I = RC->getSuperClasses(); 357c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen do { 358c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen switch (Super->getID()) { 359c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen case ARM::GPRRegClassID: 360c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen case ARM::SPRRegClassID: 361c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen case ARM::DPRRegClassID: 362c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen case ARM::QPRRegClassID: 363c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen case ARM::QQPRRegClassID: 364c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen case ARM::QQQQPRRegClassID: 365c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen return Super; 366c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen } 367c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen Super = *I++; 368c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen } while (Super); 369c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen return RC; 370c9e5015dece0a1a73bec358e11bc87594831279dJakob Stoklund Olesen} 371b990a2f249196ad3e0cc451d40a45fc2f9278eafEvan Cheng 3724f54c1293af174a8002db20faf7b4f82ba4e8514Evan Chengconst TargetRegisterClass * 3732cfd52c507bd5790457a171eb9bcb39019cc6860Chris LattnerARMBaseRegisterInfo::getPointerRegClass(unsigned Kind) const { 374e11a8f565c6a019ddc54667227be9c4d8f117473Jim Grosbach return ARM::GPRRegisterClass; 375c140c4803dc3e10e08138670829bc0494986abe9David Goodwin} 376be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich 377342e3161d9dd4fa485b47788aa0266f9c91c3832Evan Chengconst TargetRegisterClass * 378342e3161d9dd4fa485b47788aa0266f9c91c3832Evan ChengARMBaseRegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const { 379342e3161d9dd4fa485b47788aa0266f9c91c3832Evan Cheng if (RC == &ARM::CCRRegClass) 380342e3161d9dd4fa485b47788aa0266f9c91c3832Evan Cheng return 0; // Can't copy CCR registers. 381342e3161d9dd4fa485b47788aa0266f9c91c3832Evan Cheng return RC; 382342e3161d9dd4fa485b47788aa0266f9c91c3832Evan Cheng} 383342e3161d9dd4fa485b47788aa0266f9c91c3832Evan Cheng 384be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarichunsigned 385be2119e8e2bc7006cfd638a24367acbfda625d16Cameron ZwarichARMBaseRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC, 386be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich MachineFunction &MF) const { 387be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 388be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich 389be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich switch (RC->getID()) { 390be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich default: 391be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich return 0; 392be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich case ARM::tGPRRegClassID: 393be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich return TFI->hasFP(MF) ? 4 : 5; 394be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich case ARM::GPRRegClassID: { 395be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich unsigned FP = TFI->hasFP(MF) ? 1 : 0; 396be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich return 10 - FP - (STI.isR9Reserved() ? 1 : 0); 397be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich } 398be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich case ARM::SPRRegClassID: // Currently not used as 'rep' register class. 399be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich case ARM::DPRRegClassID: 400be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich return 32 - 10; 401be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich } 402be2119e8e2bc7006cfd638a24367acbfda625d16Cameron Zwarich} 403c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 404dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund Olesen/// getRawAllocationOrder - Returns the register allocation order for a 405dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund Olesen/// specified register class with a target-dependent hint. 406dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund OlesenArrayRef<unsigned> 407dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund OlesenARMBaseRegisterInfo::getRawAllocationOrder(const TargetRegisterClass *RC, 408dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund Olesen unsigned HintType, unsigned HintReg, 409dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund Olesen const MachineFunction &MF) const { 41016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 411c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // Alternative register allocation orders when favoring even / odd registers 412c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // of register pairs. 413c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 414c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // No FP, R9 is available. 415c140c4803dc3e10e08138670829bc0494986abe9David Goodwin static const unsigned GPREven1[] = { 416c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R0, ARM::R2, ARM::R4, ARM::R6, ARM::R8, ARM::R10, 417c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R7, 418c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R9, ARM::R11 419c140c4803dc3e10e08138670829bc0494986abe9David Goodwin }; 420c140c4803dc3e10e08138670829bc0494986abe9David Goodwin static const unsigned GPROdd1[] = { 421c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R1, ARM::R3, ARM::R5, ARM::R7, ARM::R9, ARM::R11, 422c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6, 423c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R8, ARM::R10 424c140c4803dc3e10e08138670829bc0494986abe9David Goodwin }; 425c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 426c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // FP is R7, R9 is available. 427c140c4803dc3e10e08138670829bc0494986abe9David Goodwin static const unsigned GPREven2[] = { 428c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R0, ARM::R2, ARM::R4, ARM::R8, ARM::R10, 429c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R6, 430c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R9, ARM::R11 431c140c4803dc3e10e08138670829bc0494986abe9David Goodwin }; 432c140c4803dc3e10e08138670829bc0494986abe9David Goodwin static const unsigned GPROdd2[] = { 433c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R1, ARM::R3, ARM::R5, ARM::R9, ARM::R11, 434c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6, 435c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R8, ARM::R10 436c140c4803dc3e10e08138670829bc0494986abe9David Goodwin }; 437c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 438c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // FP is R11, R9 is available. 439c140c4803dc3e10e08138670829bc0494986abe9David Goodwin static const unsigned GPREven3[] = { 440c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R0, ARM::R2, ARM::R4, ARM::R6, ARM::R8, 441c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R1, ARM::R3, ARM::R10,ARM::R12,ARM::LR, ARM::R5, ARM::R7, 442c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R9 443c140c4803dc3e10e08138670829bc0494986abe9David Goodwin }; 444c140c4803dc3e10e08138670829bc0494986abe9David Goodwin static const unsigned GPROdd3[] = { 445c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R1, ARM::R3, ARM::R5, ARM::R6, ARM::R9, 446c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R0, ARM::R2, ARM::R10,ARM::R12,ARM::LR, ARM::R4, ARM::R7, 447c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R8 448c140c4803dc3e10e08138670829bc0494986abe9David Goodwin }; 449c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 450c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // No FP, R9 is not available. 451c140c4803dc3e10e08138670829bc0494986abe9David Goodwin static const unsigned GPREven4[] = { 452c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R0, ARM::R2, ARM::R4, ARM::R6, ARM::R10, 453c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R7, ARM::R8, 454c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R11 455c140c4803dc3e10e08138670829bc0494986abe9David Goodwin }; 456c140c4803dc3e10e08138670829bc0494986abe9David Goodwin static const unsigned GPROdd4[] = { 457c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R1, ARM::R3, ARM::R5, ARM::R7, ARM::R11, 458c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8, 459c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R10 460c140c4803dc3e10e08138670829bc0494986abe9David Goodwin }; 461c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 462c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // FP is R7, R9 is not available. 463c140c4803dc3e10e08138670829bc0494986abe9David Goodwin static const unsigned GPREven5[] = { 464c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R0, ARM::R2, ARM::R4, ARM::R10, 465c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R6, ARM::R8, 466c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R11 467c140c4803dc3e10e08138670829bc0494986abe9David Goodwin }; 468c140c4803dc3e10e08138670829bc0494986abe9David Goodwin static const unsigned GPROdd5[] = { 469c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R1, ARM::R3, ARM::R5, ARM::R11, 470c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8, 471c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R10 472c140c4803dc3e10e08138670829bc0494986abe9David Goodwin }; 473c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 474c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // FP is R11, R9 is not available. 475c140c4803dc3e10e08138670829bc0494986abe9David Goodwin static const unsigned GPREven6[] = { 476c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R0, ARM::R2, ARM::R4, ARM::R6, 477c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R1, ARM::R3, ARM::R10,ARM::R12,ARM::LR, ARM::R5, ARM::R7, ARM::R8 478c140c4803dc3e10e08138670829bc0494986abe9David Goodwin }; 479c140c4803dc3e10e08138670829bc0494986abe9David Goodwin static const unsigned GPROdd6[] = { 480c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R1, ARM::R3, ARM::R5, ARM::R7, 481c140c4803dc3e10e08138670829bc0494986abe9David Goodwin ARM::R0, ARM::R2, ARM::R10,ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8 482c140c4803dc3e10e08138670829bc0494986abe9David Goodwin }; 483c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 484eb5067e0d9ca182f21db24949b63616ce4bb1eafJakob Stoklund Olesen // We only support even/odd hints for GPR and rGPR. 485eb5067e0d9ca182f21db24949b63616ce4bb1eafJakob Stoklund Olesen if (RC != ARM::GPRRegisterClass && RC != ARM::rGPRRegisterClass) 486dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund Olesen return RC->getRawAllocationOrder(MF); 487c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 488c140c4803dc3e10e08138670829bc0494986abe9David Goodwin if (HintType == ARMRI::RegPairEven) { 489c140c4803dc3e10e08138670829bc0494986abe9David Goodwin if (isPhysicalRegister(HintReg) && getRegisterPairEven(HintReg, MF) == 0) 490c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // It's no longer possible to fulfill this hint. Return the default 491c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // allocation order. 492dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund Olesen return RC->getRawAllocationOrder(MF); 493c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 494d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (!TFI->hasFP(MF)) { 495c140c4803dc3e10e08138670829bc0494986abe9David Goodwin if (!STI.isR9Reserved()) 49639b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel return makeArrayRef(GPREven1); 497c140c4803dc3e10e08138670829bc0494986abe9David Goodwin else 49839b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel return makeArrayRef(GPREven4); 499c140c4803dc3e10e08138670829bc0494986abe9David Goodwin } else if (FramePtr == ARM::R7) { 500c140c4803dc3e10e08138670829bc0494986abe9David Goodwin if (!STI.isR9Reserved()) 50139b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel return makeArrayRef(GPREven2); 502c140c4803dc3e10e08138670829bc0494986abe9David Goodwin else 50339b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel return makeArrayRef(GPREven5); 504c140c4803dc3e10e08138670829bc0494986abe9David Goodwin } else { // FramePtr == ARM::R11 505c140c4803dc3e10e08138670829bc0494986abe9David Goodwin if (!STI.isR9Reserved()) 50639b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel return makeArrayRef(GPREven3); 507c140c4803dc3e10e08138670829bc0494986abe9David Goodwin else 50839b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel return makeArrayRef(GPREven6); 509c140c4803dc3e10e08138670829bc0494986abe9David Goodwin } 510c140c4803dc3e10e08138670829bc0494986abe9David Goodwin } else if (HintType == ARMRI::RegPairOdd) { 511c140c4803dc3e10e08138670829bc0494986abe9David Goodwin if (isPhysicalRegister(HintReg) && getRegisterPairOdd(HintReg, MF) == 0) 512c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // It's no longer possible to fulfill this hint. Return the default 513c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // allocation order. 514dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund Olesen return RC->getRawAllocationOrder(MF); 515c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 516d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (!TFI->hasFP(MF)) { 517c140c4803dc3e10e08138670829bc0494986abe9David Goodwin if (!STI.isR9Reserved()) 51839b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel return makeArrayRef(GPROdd1); 519c140c4803dc3e10e08138670829bc0494986abe9David Goodwin else 52039b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel return makeArrayRef(GPROdd4); 521c140c4803dc3e10e08138670829bc0494986abe9David Goodwin } else if (FramePtr == ARM::R7) { 522c140c4803dc3e10e08138670829bc0494986abe9David Goodwin if (!STI.isR9Reserved()) 52339b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel return makeArrayRef(GPROdd2); 524c140c4803dc3e10e08138670829bc0494986abe9David Goodwin else 52539b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel return makeArrayRef(GPROdd5); 526c140c4803dc3e10e08138670829bc0494986abe9David Goodwin } else { // FramePtr == ARM::R11 527c140c4803dc3e10e08138670829bc0494986abe9David Goodwin if (!STI.isR9Reserved()) 52839b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel return makeArrayRef(GPROdd3); 529c140c4803dc3e10e08138670829bc0494986abe9David Goodwin else 53039b5abf507b43da6b92f68b86406e0015ead18e9Frits van Bommel return makeArrayRef(GPROdd6); 531c140c4803dc3e10e08138670829bc0494986abe9David Goodwin } 532c140c4803dc3e10e08138670829bc0494986abe9David Goodwin } 533dd5a8471526ceadf9bceb1a1221299b3db49c33aJakob Stoklund Olesen return RC->getRawAllocationOrder(MF); 534c140c4803dc3e10e08138670829bc0494986abe9David Goodwin} 535c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 536c140c4803dc3e10e08138670829bc0494986abe9David Goodwin/// ResolveRegAllocHint - Resolves the specified register allocation hint 537c140c4803dc3e10e08138670829bc0494986abe9David Goodwin/// to a physical register. Returns the physical register if it is successful. 538c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned 539c140c4803dc3e10e08138670829bc0494986abe9David GoodwinARMBaseRegisterInfo::ResolveRegAllocHint(unsigned Type, unsigned Reg, 540c140c4803dc3e10e08138670829bc0494986abe9David Goodwin const MachineFunction &MF) const { 541c140c4803dc3e10e08138670829bc0494986abe9David Goodwin if (Reg == 0 || !isPhysicalRegister(Reg)) 542c140c4803dc3e10e08138670829bc0494986abe9David Goodwin return 0; 543c140c4803dc3e10e08138670829bc0494986abe9David Goodwin if (Type == 0) 544c140c4803dc3e10e08138670829bc0494986abe9David Goodwin return Reg; 545c140c4803dc3e10e08138670829bc0494986abe9David Goodwin else if (Type == (unsigned)ARMRI::RegPairOdd) 546c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // Odd register. 547c140c4803dc3e10e08138670829bc0494986abe9David Goodwin return getRegisterPairOdd(Reg, MF); 548c140c4803dc3e10e08138670829bc0494986abe9David Goodwin else if (Type == (unsigned)ARMRI::RegPairEven) 549c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // Even register. 550c140c4803dc3e10e08138670829bc0494986abe9David Goodwin return getRegisterPairEven(Reg, MF); 551c140c4803dc3e10e08138670829bc0494986abe9David Goodwin return 0; 552c140c4803dc3e10e08138670829bc0494986abe9David Goodwin} 553c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 554c140c4803dc3e10e08138670829bc0494986abe9David Goodwinvoid 555c140c4803dc3e10e08138670829bc0494986abe9David GoodwinARMBaseRegisterInfo::UpdateRegAllocHint(unsigned Reg, unsigned NewReg, 556c140c4803dc3e10e08138670829bc0494986abe9David Goodwin MachineFunction &MF) const { 557c140c4803dc3e10e08138670829bc0494986abe9David Goodwin MachineRegisterInfo *MRI = &MF.getRegInfo(); 558c140c4803dc3e10e08138670829bc0494986abe9David Goodwin std::pair<unsigned, unsigned> Hint = MRI->getRegAllocationHint(Reg); 559c140c4803dc3e10e08138670829bc0494986abe9David Goodwin if ((Hint.first == (unsigned)ARMRI::RegPairOdd || 560c140c4803dc3e10e08138670829bc0494986abe9David Goodwin Hint.first == (unsigned)ARMRI::RegPairEven) && 561c9df025e33ac435adb3b3318d237c36ca7cec659Jakob Stoklund Olesen TargetRegisterInfo::isVirtualRegister(Hint.second)) { 562c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // If 'Reg' is one of the even / odd register pair and it's now changed 563c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // (e.g. coalesced) into a different register. The other register of the 564c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // pair allocation hint must be updated to reflect the relationship 565c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // change. 566c140c4803dc3e10e08138670829bc0494986abe9David Goodwin unsigned OtherReg = Hint.second; 567c140c4803dc3e10e08138670829bc0494986abe9David Goodwin Hint = MRI->getRegAllocationHint(OtherReg); 568c140c4803dc3e10e08138670829bc0494986abe9David Goodwin if (Hint.second == Reg) 569c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // Make sure the pair has not already divorced. 570c140c4803dc3e10e08138670829bc0494986abe9David Goodwin MRI->setRegAllocationHint(OtherReg, Hint.first, NewReg); 571c140c4803dc3e10e08138670829bc0494986abe9David Goodwin } 572c140c4803dc3e10e08138670829bc0494986abe9David Goodwin} 573f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson 574f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilsonbool 575f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob WilsonARMBaseRegisterInfo::avoidWriteAfterWrite(const TargetRegisterClass *RC) const { 576f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson // CortexA9 has a Write-after-write hazard for NEON registers. 577f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson if (!STI.isCortexA9()) 578f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson return false; 579f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson 580f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson switch (RC->getID()) { 581f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson case ARM::DPRRegClassID: 582f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson case ARM::DPR_8RegClassID: 583f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson case ARM::DPR_VFP2RegClassID: 584f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson case ARM::QPRRegClassID: 585f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson case ARM::QPR_8RegClassID: 586f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson case ARM::QPR_VFP2RegClassID: 587f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson case ARM::SPRRegClassID: 588f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson case ARM::SPR_8RegClassID: 589f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson // Avoid reusing S, D, and Q registers. 590f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson // Don't increase register pressure for QQ and QQQQ. 591f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson return true; 592f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson default: 593f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson return false; 594f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson } 595f6a4d3c2f3e1029af252a0f6999edfa3c2f326eeBob Wilson} 596c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 59765482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbachbool ARMBaseRegisterInfo::hasBasePointer(const MachineFunction &MF) const { 5986a8700301ca6f8f2f5f787c8d1f5206a7dfceed6Daniel Dunbar const MachineFrameInfo *MFI = MF.getFrameInfo(); 5991755b3964f931bdd6fa9b4c0138f666ccfa12acaJim Grosbach const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 60065482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach 60165482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach if (!EnableBasePointer) 60265482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach return false; 60365482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach 60465482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach if (needsStackRealignment(MF) && MFI->hasVarSizedObjects()) 60565482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach return true; 60665482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach 60765482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach // Thumb has trouble with negative offsets from the FP. Thumb2 has a limited 60865482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach // negative range for ldr/str (255), and thumb1 is positive offsets only. 60965482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach // It's going to be better to use the SP or Base Pointer instead. When there 61065482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach // are variable sized objects, we can't reference off of the SP, so we 61165482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach // reserve a Base Pointer. 61265482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach if (AFI->isThumbFunction() && MFI->hasVarSizedObjects()) { 61365482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach // Conservatively estimate whether the negative offset from the frame 61465482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach // pointer will be sufficient to reach. If a function has a smallish 61565482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach // frame, it's less likely to have lots of spills and callee saved 61665482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach // space, so it's all more likely to be within range of the frame pointer. 61765482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach // If it's wrong, the scavenger will still enable access to work, it just 61865482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach // won't be optimal. 61965482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach if (AFI->isThumb2Function() && MFI->getLocalFrameSize() < 128) 62065482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach return false; 62165482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach return true; 62265482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach } 62365482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach 62465482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach return false; 62565482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach} 62665482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach 62765482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbachbool ARMBaseRegisterInfo::canRealignStack(const MachineFunction &MF) const { 62830c93e1cd3e43e174994834900325fcff3322288Jim Grosbach const MachineFrameInfo *MFI = MF.getFrameInfo(); 6296690bca623d1f6405b95db5b1760f7ba8436e3fbChad Rosier const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 63030c93e1cd3e43e174994834900325fcff3322288Jim Grosbach // We can't realign the stack if: 63130c93e1cd3e43e174994834900325fcff3322288Jim Grosbach // 1. Dynamic stack realignment is explicitly disabled, 6326690bca623d1f6405b95db5b1760f7ba8436e3fbChad Rosier // 2. This is a Thumb1 function (it's not useful, so we don't bother), or 6336690bca623d1f6405b95db5b1760f7ba8436e3fbChad Rosier // 3. There are VLAs in the function and the base pointer is disabled. 6348a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky return (MF.getTarget().Options.RealignStack && !AFI->isThumb1OnlyFunction() && 6356690bca623d1f6405b95db5b1760f7ba8436e3fbChad Rosier (!MFI->hasVarSizedObjects() || EnableBasePointer)); 636e45ab8a0a90e4f3a59d8c38038ae3e495ee1fef3Jim Grosbach} 637e45ab8a0a90e4f3a59d8c38038ae3e495ee1fef3Jim Grosbach 6383dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbachbool ARMBaseRegisterInfo:: 6393dab2778571b5bb00b35a0adcb7011dc85158bebJim GrosbachneedsStackRealignment(const MachineFunction &MF) const { 6403dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach const MachineFrameInfo *MFI = MF.getFrameInfo(); 641d4c36cec1db81b4ee48cd4ab462262615d78f22cEric Christopher const Function *F = MF.getFunction(); 64216c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov unsigned StackAlign = MF.getTarget().getFrameLowering()->getStackAlignment(); 643fc633002339439339e94f83eca9a012c6fc51e50Jim Grosbach bool requiresRealignment = ((MFI->getLocalFrameMaxAlign() > StackAlign) || 644697cba8ec2b3f5160175fd5b4a641dbd48606e17Eric Christopher F->hasFnAttr(Attribute::StackAlignment)); 6455c33f5bf67f61e3a1addda6de735d28d550dd0ebJim Grosbach 646d4c36cec1db81b4ee48cd4ab462262615d78f22cEric Christopher return requiresRealignment && canRealignStack(MF); 6473dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach} 6483dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach 6499631864688c593711f82bb8d21f8b724c628d786Jim Grosbachbool ARMBaseRegisterInfo:: 6509631864688c593711f82bb8d21f8b724c628d786Jim GrosbachcannotEliminateFrame(const MachineFunction &MF) const { 65198a0104014e9bb6ed89c2572f615351fd526674aEvan Cheng const MachineFrameInfo *MFI = MF.getFrameInfo(); 6528a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky if (MF.getTarget().Options.DisableFramePointerElim(MF) && MFI->adjustsStack()) 65398a0104014e9bb6ed89c2572f615351fd526674aEvan Cheng return true; 65431bc849123011b8eae6bb3c79876d9a3c26a6a1dJim Grosbach return MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken() 65531bc849123011b8eae6bb3c79876d9a3c26a6a1dJim Grosbach || needsStackRealignment(MF); 65698a0104014e9bb6ed89c2572f615351fd526674aEvan Cheng} 65798a0104014e9bb6ed89c2572f615351fd526674aEvan Cheng 6585c33f5bf67f61e3a1addda6de735d28d550dd0ebJim Grosbachunsigned 6593f2bf85d14759cc4b28a86805f566ac805a54d00David GreeneARMBaseRegisterInfo::getFrameRegister(const MachineFunction &MF) const { 66016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 661d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 662d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (TFI->hasFP(MF)) 663c140c4803dc3e10e08138670829bc0494986abe9David Goodwin return FramePtr; 664c140c4803dc3e10e08138670829bc0494986abe9David Goodwin return ARM::SP; 665c140c4803dc3e10e08138670829bc0494986abe9David Goodwin} 666c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 667c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned ARMBaseRegisterInfo::getEHExceptionRegister() const { 668c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("What is the exception register"); 669c140c4803dc3e10e08138670829bc0494986abe9David Goodwin return 0; 670c140c4803dc3e10e08138670829bc0494986abe9David Goodwin} 671c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 672c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned ARMBaseRegisterInfo::getEHHandlerRegister() const { 673c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("What is the exception handler register"); 674c140c4803dc3e10e08138670829bc0494986abe9David Goodwin return 0; 675c140c4803dc3e10e08138670829bc0494986abe9David Goodwin} 676c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 677c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned ARMBaseRegisterInfo::getRegisterPairEven(unsigned Reg, 6789631864688c593711f82bb8d21f8b724c628d786Jim Grosbach const MachineFunction &MF) const { 679c140c4803dc3e10e08138670829bc0494986abe9David Goodwin switch (Reg) { 680c140c4803dc3e10e08138670829bc0494986abe9David Goodwin default: break; 681c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // Return 0 if either register of the pair is a special register. 682c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // So no R12, etc. 6838f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::R1: return ARM::R0; 6848f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::R3: return ARM::R2; 6858f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::R5: return ARM::R4; 686c140c4803dc3e10e08138670829bc0494986abe9David Goodwin case ARM::R7: 68765482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach return (isReservedReg(MF, ARM::R7) || isReservedReg(MF, ARM::R6)) 68865482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach ? 0 : ARM::R6; 6898f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::R9: return isReservedReg(MF, ARM::R9) ? 0 :ARM::R8; 6908f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::R11: return isReservedReg(MF, ARM::R11) ? 0 : ARM::R10; 6918f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach 6928f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S1: return ARM::S0; 6938f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S3: return ARM::S2; 6948f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S5: return ARM::S4; 6958f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S7: return ARM::S6; 6968f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S9: return ARM::S8; 6978f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S11: return ARM::S10; 6988f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S13: return ARM::S12; 6998f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S15: return ARM::S14; 7008f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S17: return ARM::S16; 7018f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S19: return ARM::S18; 7028f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S21: return ARM::S20; 7038f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S23: return ARM::S22; 7048f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S25: return ARM::S24; 7058f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S27: return ARM::S26; 7068f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S29: return ARM::S28; 7078f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S31: return ARM::S30; 7088f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach 7098f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D1: return ARM::D0; 7108f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D3: return ARM::D2; 7118f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D5: return ARM::D4; 7128f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D7: return ARM::D6; 7138f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D9: return ARM::D8; 7148f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D11: return ARM::D10; 7158f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D13: return ARM::D12; 7168f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D15: return ARM::D14; 7178f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D17: return ARM::D16; 7188f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D19: return ARM::D18; 7198f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D21: return ARM::D20; 7208f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D23: return ARM::D22; 7218f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D25: return ARM::D24; 7228f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D27: return ARM::D26; 7238f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D29: return ARM::D28; 7248f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D31: return ARM::D30; 725c140c4803dc3e10e08138670829bc0494986abe9David Goodwin } 726c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 727c140c4803dc3e10e08138670829bc0494986abe9David Goodwin return 0; 728c140c4803dc3e10e08138670829bc0494986abe9David Goodwin} 729c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 730c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned ARMBaseRegisterInfo::getRegisterPairOdd(unsigned Reg, 731c140c4803dc3e10e08138670829bc0494986abe9David Goodwin const MachineFunction &MF) const { 732c140c4803dc3e10e08138670829bc0494986abe9David Goodwin switch (Reg) { 733c140c4803dc3e10e08138670829bc0494986abe9David Goodwin default: break; 734c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // Return 0 if either register of the pair is a special register. 735c140c4803dc3e10e08138670829bc0494986abe9David Goodwin // So no R12, etc. 7368f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::R0: return ARM::R1; 7378f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::R2: return ARM::R3; 7388f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::R4: return ARM::R5; 739c140c4803dc3e10e08138670829bc0494986abe9David Goodwin case ARM::R6: 74065482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach return (isReservedReg(MF, ARM::R7) || isReservedReg(MF, ARM::R6)) 74165482b1bb873dd820f54a24a2f34bd65f2669e5cJim Grosbach ? 0 : ARM::R7; 7428f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::R8: return isReservedReg(MF, ARM::R9) ? 0 :ARM::R9; 7438f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::R10: return isReservedReg(MF, ARM::R11) ? 0 : ARM::R11; 7448f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach 7458f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S0: return ARM::S1; 7468f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S2: return ARM::S3; 7478f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S4: return ARM::S5; 7488f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S6: return ARM::S7; 7498f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S8: return ARM::S9; 7508f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S10: return ARM::S11; 7518f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S12: return ARM::S13; 7528f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S14: return ARM::S15; 7538f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S16: return ARM::S17; 7548f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S18: return ARM::S19; 7558f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S20: return ARM::S21; 7568f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S22: return ARM::S23; 7578f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S24: return ARM::S25; 7588f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S26: return ARM::S27; 7598f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S28: return ARM::S29; 7608f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::S30: return ARM::S31; 7618f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach 7628f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D0: return ARM::D1; 7638f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D2: return ARM::D3; 7648f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D4: return ARM::D5; 7658f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D6: return ARM::D7; 7668f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D8: return ARM::D9; 7678f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D10: return ARM::D11; 7688f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D12: return ARM::D13; 7698f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D14: return ARM::D15; 7708f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D16: return ARM::D17; 7718f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D18: return ARM::D19; 7728f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D20: return ARM::D21; 7738f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D22: return ARM::D23; 7748f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D24: return ARM::D25; 7758f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D26: return ARM::D27; 7768f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D28: return ARM::D29; 7778f310d978681b08e2e134a1d7b0433e43aa909f2Jim Grosbach case ARM::D30: return ARM::D31; 778c140c4803dc3e10e08138670829bc0494986abe9David Goodwin } 779c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 780c140c4803dc3e10e08138670829bc0494986abe9David Goodwin return 0; 781c140c4803dc3e10e08138670829bc0494986abe9David Goodwin} 782c140c4803dc3e10e08138670829bc0494986abe9David Goodwin 783db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin/// emitLoadConstPool - Emits a load from constpool to materialize the 784db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin/// specified immediate. 785db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinvoid ARMBaseRegisterInfo:: 786db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwinemitLoadConstPool(MachineBasicBlock &MBB, 787db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin MachineBasicBlock::iterator &MBBI, 78877521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin DebugLoc dl, 789378445303b10b092a898a75131141a8259cff50bEvan Cheng unsigned DestReg, unsigned SubIdx, int Val, 790db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin ARMCC::CondCodes Pred, 7913daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov unsigned PredReg, unsigned MIFlags) const { 792db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin MachineFunction &MF = *MBB.getParent(); 793db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin MachineConstantPool *ConstantPool = MF.getConstantPool(); 79446510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const Constant *C = 7951d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson ConstantInt::get(Type::getInt32Ty(MF.getFunction()->getContext()), Val); 796db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4); 797db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin 798378445303b10b092a898a75131141a8259cff50bEvan Cheng BuildMI(MBB, MBBI, dl, TII.get(ARM::LDRcp)) 799378445303b10b092a898a75131141a8259cff50bEvan Cheng .addReg(DestReg, getDefRegState(true), SubIdx) 800db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin .addConstantPoolIndex(Idx) 8013daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov .addImm(0).addImm(Pred).addReg(PredReg) 8023daccd82d3151fa3629de430b55698a81084fc9eAnton Korobeynikov .setMIFlags(MIFlags); 803db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin} 804db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin 805db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinbool ARMBaseRegisterInfo:: 806db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwinrequiresRegisterScavenging(const MachineFunction &MF) const { 807db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin return true; 808db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin} 80941fff8c19ab6d8e28f5362481c184ad628f8c704Jim Grosbach 8107e831db1d4f5dc51ca6526739cf41e59895c5c20Jim Grosbachbool ARMBaseRegisterInfo:: 8117e831db1d4f5dc51ca6526739cf41e59895c5c20Jim GrosbachrequiresFrameIndexScavenging(const MachineFunction &MF) const { 812ca5dfb71ba4aa4a8392a021ec056cf0b70f74f1eJim Grosbach return true; 8137e831db1d4f5dc51ca6526739cf41e59895c5c20Jim Grosbach} 814db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin 815a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbachbool ARMBaseRegisterInfo:: 816a273442891ae20fd8192526132e3819ea9e5eda9Jim GrosbachrequiresVirtualBaseRegisters(const MachineFunction &MF) const { 817a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbach return EnableLocalStackAlloc; 818a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbach} 819a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbach 820db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinstatic void 8216495f63945e8dbde81f03a1dc2ab421993b9a495Evan ChengemitSPUpdate(bool isARM, 8226495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 8236495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng DebugLoc dl, const ARMBaseInstrInfo &TII, 824db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin int NumBytes, 825db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin ARMCC::CondCodes Pred = ARMCC::AL, unsigned PredReg = 0) { 8266495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng if (isARM) 8276495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng emitARMRegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes, 8286495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng Pred, PredReg, TII); 8296495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng else 8306495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng emitT2RegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes, 8316495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng Pred, PredReg, TII); 832db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin} 833db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin 8346495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 835db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinvoid ARMBaseRegisterInfo:: 836db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwineliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 837db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin MachineBasicBlock::iterator I) const { 83816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 839d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (!TFI->hasReservedCallFrame(MF)) { 840db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin // If we have alloca, convert as follows: 841db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin // ADJCALLSTACKDOWN -> sub, sp, sp, amount 842db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin // ADJCALLSTACKUP -> add, sp, sp, amount 843db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin MachineInstr *Old = I; 844db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin DebugLoc dl = Old->getDebugLoc(); 845db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin unsigned Amount = Old->getOperand(0).getImm(); 846db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin if (Amount != 0) { 847db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin // We need to keep the stack aligned properly. To do this, we round the 848db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin // amount of space needed for the outgoing arguments up to the next 849db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin // alignment boundary. 85016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov unsigned Align = TFI->getStackAlignment(); 851db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin Amount = (Amount+Align-1)/Align*Align; 852db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin 8536495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 8546495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng assert(!AFI->isThumb1OnlyFunction() && 855cf453ee70a1ae03cc641686fd5db0f8a7d8ce250Jim Grosbach "This eliminateCallFramePseudoInstr does not support Thumb1!"); 8566495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng bool isARM = !AFI->isThumbFunction(); 8576495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng 858db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin // Replace the pseudo instruction with a new instruction... 859db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin unsigned Opc = Old->getOpcode(); 8604c7628e43d8468f215ea345545479b6d728cee92Jim Grosbach int PIdx = Old->findFirstPredOperandIdx(); 8614c7628e43d8468f215ea345545479b6d728cee92Jim Grosbach ARMCC::CondCodes Pred = (PIdx == -1) 8624c7628e43d8468f215ea345545479b6d728cee92Jim Grosbach ? ARMCC::AL : (ARMCC::CondCodes)Old->getOperand(PIdx).getImm(); 863db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) { 864db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin // Note: PredReg is operand 2 for ADJCALLSTACKDOWN. 865db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin unsigned PredReg = Old->getOperand(2).getReg(); 8666495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng emitSPUpdate(isARM, MBB, I, dl, TII, -Amount, Pred, PredReg); 867db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin } else { 868db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin // Note: PredReg is operand 3 for ADJCALLSTACKUP. 869db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin unsigned PredReg = Old->getOperand(3).getReg(); 870db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP); 8716495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng emitSPUpdate(isARM, MBB, I, dl, TII, Amount, Pred, PredReg); 872db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin } 873db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin } 874db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin } 875db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin MBB.erase(I); 876db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin} 877db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin 878e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbachint64_t ARMBaseRegisterInfo:: 8791ab3f16f06698596716593a30545799688acccd7Jim GrosbachgetFrameIndexInstrOffset(const MachineInstr *MI, int Idx) const { 880e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng const MCInstrDesc &Desc = MI->getDesc(); 881e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); 882e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach int64_t InstrOffs = 0;; 883e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach int Scale = 1; 884e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach unsigned ImmIdx = 0; 8851ab3f16f06698596716593a30545799688acccd7Jim Grosbach switch (AddrMode) { 886e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach case ARMII::AddrModeT2_i8: 887e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach case ARMII::AddrModeT2_i12: 8883e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach case ARMII::AddrMode_i12: 889e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach InstrOffs = MI->getOperand(Idx+1).getImm(); 890e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach Scale = 1; 891e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach break; 892e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach case ARMII::AddrMode5: { 893e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach // VFP address mode. 894e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach const MachineOperand &OffOp = MI->getOperand(Idx+1); 895f78ee6316bc755779920ac207edc27a89c0bd2f9Jim Grosbach InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm()); 896e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub) 897e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach InstrOffs = -InstrOffs; 898e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach Scale = 4; 899e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach break; 900e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach } 901e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach case ARMII::AddrMode2: { 902e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach ImmIdx = Idx+2; 903e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach InstrOffs = ARM_AM::getAM2Offset(MI->getOperand(ImmIdx).getImm()); 904e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach if (ARM_AM::getAM2Op(MI->getOperand(ImmIdx).getImm()) == ARM_AM::sub) 905e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach InstrOffs = -InstrOffs; 906e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach break; 907e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach } 908e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach case ARMII::AddrMode3: { 909e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach ImmIdx = Idx+2; 910e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach InstrOffs = ARM_AM::getAM3Offset(MI->getOperand(ImmIdx).getImm()); 911e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach if (ARM_AM::getAM3Op(MI->getOperand(ImmIdx).getImm()) == ARM_AM::sub) 912e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach InstrOffs = -InstrOffs; 913e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach break; 914e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach } 915e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach case ARMII::AddrModeT1_s: { 916e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach ImmIdx = Idx+1; 917e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach InstrOffs = MI->getOperand(ImmIdx).getImm(); 918e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach Scale = 4; 919e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach break; 920e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach } 921e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach default: 922e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach llvm_unreachable("Unsupported addressing mode!"); 923e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach break; 924e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach } 925e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach 926e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach return InstrOffs * Scale; 927e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach} 928e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach 9298708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach/// needsFrameBaseReg - Returns true if the instruction's frame index 9308708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach/// reference would be better served by a base register other than FP 9318708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach/// or SP. Used by LocalStackFrameAllocation to determine which frame index 9328708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach/// references it should create new base registers for. 9338708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbachbool ARMBaseRegisterInfo:: 9343197380143cdc18837722129ac888528b9fbfc2bJim GrosbachneedsFrameBaseReg(MachineInstr *MI, int64_t Offset) const { 9353197380143cdc18837722129ac888528b9fbfc2bJim Grosbach for (unsigned i = 0; !MI->getOperand(i).isFI(); ++i) { 9363197380143cdc18837722129ac888528b9fbfc2bJim Grosbach assert(i < MI->getNumOperands() &&"Instr doesn't have FrameIndex operand!"); 9373197380143cdc18837722129ac888528b9fbfc2bJim Grosbach } 9388708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach 9398708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // It's the load/store FI references that cause issues, as it can be difficult 9408708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // to materialize the offset if it won't fit in the literal field. Estimate 9418708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // based on the size of the local frame and some conservative assumptions 9428708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // about the rest of the stack frame (note, this is pre-regalloc, so 9438708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // we don't know everything for certain yet) whether this offset is likely 9448708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // to be out of range of the immediate. Return true if so. 9458708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach 946cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach // We only generate virtual base registers for loads and stores, so 947cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach // return false for everything else. 9488708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach unsigned Opc = MI->getOpcode(); 9498708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach switch (Opc) { 950c1d30212e911d1e55ff6b25bffefb503708883c3Jim Grosbach case ARM::LDRi12: case ARM::LDRH: case ARM::LDRBi12: 9517e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach case ARM::STRi12: case ARM::STRH: case ARM::STRBi12: 9528708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach case ARM::t2LDRi12: case ARM::t2LDRi8: 9538708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach case ARM::t2STRi12: case ARM::t2STRi8: 9548708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach case ARM::VLDRS: case ARM::VLDRD: 9558708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach case ARM::VSTRS: case ARM::VSTRD: 95674d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach case ARM::tSTRspi: case ARM::tLDRspi: 957cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach if (ForceAllBaseRegAlloc) 958cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach return true; 959cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach break; 9608708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach default: 9618708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach return false; 9628708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach } 963cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach 964cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach // Without a virtual base register, if the function has variable sized 965cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach // objects, all fixed-size local references will be via the frame pointer, 9663197380143cdc18837722129ac888528b9fbfc2bJim Grosbach // Approximate the offset and see if it's legal for the instruction. 9673197380143cdc18837722129ac888528b9fbfc2bJim Grosbach // Note that the incoming offset is based on the SP value at function entry, 9683197380143cdc18837722129ac888528b9fbfc2bJim Grosbach // so it'll be negative. 9693197380143cdc18837722129ac888528b9fbfc2bJim Grosbach MachineFunction &MF = *MI->getParent()->getParent(); 97016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 9713197380143cdc18837722129ac888528b9fbfc2bJim Grosbach MachineFrameInfo *MFI = MF.getFrameInfo(); 9723197380143cdc18837722129ac888528b9fbfc2bJim Grosbach ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 9733197380143cdc18837722129ac888528b9fbfc2bJim Grosbach 9743197380143cdc18837722129ac888528b9fbfc2bJim Grosbach // Estimate an offset from the frame pointer. 9753197380143cdc18837722129ac888528b9fbfc2bJim Grosbach // Conservatively assume all callee-saved registers get pushed. R4-R6 9763197380143cdc18837722129ac888528b9fbfc2bJim Grosbach // will be earlier than the FP, so we ignore those. 9773197380143cdc18837722129ac888528b9fbfc2bJim Grosbach // R7, LR 9783197380143cdc18837722129ac888528b9fbfc2bJim Grosbach int64_t FPOffset = Offset - 8; 9793197380143cdc18837722129ac888528b9fbfc2bJim Grosbach // ARM and Thumb2 functions also need to consider R8-R11 and D8-D15 9803197380143cdc18837722129ac888528b9fbfc2bJim Grosbach if (!AFI->isThumbFunction() || !AFI->isThumb1OnlyFunction()) 9813197380143cdc18837722129ac888528b9fbfc2bJim Grosbach FPOffset -= 80; 9823197380143cdc18837722129ac888528b9fbfc2bJim Grosbach // Estimate an offset from the stack pointer. 983c1dc78de762e8a65fe1edd0cced13d94ab5a971fJim Grosbach // The incoming offset is relating to the SP at the start of the function, 984c1dc78de762e8a65fe1edd0cced13d94ab5a971fJim Grosbach // but when we access the local it'll be relative to the SP after local 985c1dc78de762e8a65fe1edd0cced13d94ab5a971fJim Grosbach // allocation, so adjust our SP-relative offset by that allocation size. 9863197380143cdc18837722129ac888528b9fbfc2bJim Grosbach Offset = -Offset; 987c1dc78de762e8a65fe1edd0cced13d94ab5a971fJim Grosbach Offset += MFI->getLocalFrameSize(); 9883197380143cdc18837722129ac888528b9fbfc2bJim Grosbach // Assume that we'll have at least some spill slots allocated. 9893197380143cdc18837722129ac888528b9fbfc2bJim Grosbach // FIXME: This is a total SWAG number. We should run some statistics 9903197380143cdc18837722129ac888528b9fbfc2bJim Grosbach // and pick a real one. 9913197380143cdc18837722129ac888528b9fbfc2bJim Grosbach Offset += 128; // 128 bytes of spill slots 9923197380143cdc18837722129ac888528b9fbfc2bJim Grosbach 9933197380143cdc18837722129ac888528b9fbfc2bJim Grosbach // If there is a frame pointer, try using it. 9943197380143cdc18837722129ac888528b9fbfc2bJim Grosbach // The FP is only available if there is no dynamic realignment. We 9953197380143cdc18837722129ac888528b9fbfc2bJim Grosbach // don't know for sure yet whether we'll need that, so we guess based 9963197380143cdc18837722129ac888528b9fbfc2bJim Grosbach // on whether there are any local variables that would trigger it. 99716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov unsigned StackAlign = TFI->getStackAlignment(); 998d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (TFI->hasFP(MF) && 9993197380143cdc18837722129ac888528b9fbfc2bJim Grosbach !((MFI->getLocalFrameMaxAlign() > StackAlign) && canRealignStack(MF))) { 10003197380143cdc18837722129ac888528b9fbfc2bJim Grosbach if (isFrameOffsetLegal(MI, FPOffset)) 10013197380143cdc18837722129ac888528b9fbfc2bJim Grosbach return false; 10023197380143cdc18837722129ac888528b9fbfc2bJim Grosbach } 10033197380143cdc18837722129ac888528b9fbfc2bJim Grosbach // If we can reference via the stack pointer, try that. 10043197380143cdc18837722129ac888528b9fbfc2bJim Grosbach // FIXME: This (and the code that resolves the references) can be improved 10053197380143cdc18837722129ac888528b9fbfc2bJim Grosbach // to only disallow SP relative references in the live range of 10063197380143cdc18837722129ac888528b9fbfc2bJim Grosbach // the VLA(s). In practice, it's unclear how much difference that 10073197380143cdc18837722129ac888528b9fbfc2bJim Grosbach // would make, but it may be worth doing. 10083197380143cdc18837722129ac888528b9fbfc2bJim Grosbach if (!MFI->hasVarSizedObjects() && isFrameOffsetLegal(MI, Offset)) 10093197380143cdc18837722129ac888528b9fbfc2bJim Grosbach return false; 1010cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach 10113197380143cdc18837722129ac888528b9fbfc2bJim Grosbach // The offset likely isn't legal, we want to allocate a virtual base register. 1012cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach return true; 10138708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach} 10148708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach 1015976ef86689ed065361a748f81c44ca3510af2202Bill Wendling/// materializeFrameBaseRegister - Insert defining instruction(s) for BaseReg to 1016976ef86689ed065361a748f81c44ca3510af2202Bill Wendling/// be a pointer to FrameIdx at the beginning of the basic block. 1017dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbachvoid ARMBaseRegisterInfo:: 1018976ef86689ed065361a748f81c44ca3510af2202Bill WendlingmaterializeFrameBaseRegister(MachineBasicBlock *MBB, 1019976ef86689ed065361a748f81c44ca3510af2202Bill Wendling unsigned BaseReg, int FrameIdx, 1020976ef86689ed065361a748f81c44ca3510af2202Bill Wendling int64_t Offset) const { 1021976ef86689ed065361a748f81c44ca3510af2202Bill Wendling ARMFunctionInfo *AFI = MBB->getParent()->getInfo<ARMFunctionInfo>(); 102274d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach unsigned ADDriOpc = !AFI->isThumbFunction() ? ARM::ADDri : 102374d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach (AFI->isThumb1OnlyFunction() ? ARM::tADDrSPi : ARM::t2ADDri); 1024dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach 1025976ef86689ed065361a748f81c44ca3510af2202Bill Wendling MachineBasicBlock::iterator Ins = MBB->begin(); 1026976ef86689ed065361a748f81c44ca3510af2202Bill Wendling DebugLoc DL; // Defaults to "unknown" 1027976ef86689ed065361a748f81c44ca3510af2202Bill Wendling if (Ins != MBB->end()) 1028976ef86689ed065361a748f81c44ca3510af2202Bill Wendling DL = Ins->getDebugLoc(); 1029976ef86689ed065361a748f81c44ca3510af2202Bill Wendling 1030e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng const MCInstrDesc &MCID = TII.get(ADDriOpc); 103121803721d538255e4d223c29b6c8d3c9e93d4d86Cameron Zwarich MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo(); 1032e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng MRI.constrainRegClass(BaseReg, TII.getRegClass(MCID, 0, this)); 103321803721d538255e4d223c29b6c8d3c9e93d4d86Cameron Zwarich 10345b81584f7403ffdb9cc6babaaeb0411c080e0f81Jim Grosbach MachineInstrBuilder MIB = AddDefaultPred(BuildMI(*MBB, Ins, DL, MCID, BaseReg) 10355b81584f7403ffdb9cc6babaaeb0411c080e0f81Jim Grosbach .addFrameIndex(FrameIdx).addImm(Offset)); 1036976ef86689ed065361a748f81c44ca3510af2202Bill Wendling 103774d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach if (!AFI->isThumb1OnlyFunction()) 10385b81584f7403ffdb9cc6babaaeb0411c080e0f81Jim Grosbach AddDefaultCC(MIB); 1039dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach} 1040dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach 1041dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbachvoid 1042dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim GrosbachARMBaseRegisterInfo::resolveFrameIndex(MachineBasicBlock::iterator I, 1043dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach unsigned BaseReg, int64_t Offset) const { 1044dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach MachineInstr &MI = *I; 1045dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach MachineBasicBlock &MBB = *MI.getParent(); 1046dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach MachineFunction &MF = *MBB.getParent(); 1047dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 1048dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach int Off = Offset; // ARM doesn't need the general 64-bit offsets 1049dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach unsigned i = 0; 1050dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach 1051dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach assert(!AFI->isThumb1OnlyFunction() && 1052dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach "This resolveFrameIndex does not support Thumb1!"); 1053dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach 1054dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach while (!MI.getOperand(i).isFI()) { 1055dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach ++i; 1056dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 1057dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach } 1058dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach bool Done = false; 1059dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach if (!AFI->isThumbFunction()) 1060dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach Done = rewriteARMFrameIndex(MI, i, BaseReg, Off, TII); 1061dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach else { 1062dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach assert(AFI->isThumb2Function()); 1063dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach Done = rewriteT2FrameIndex(MI, i, BaseReg, Off, TII); 1064dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach } 1065dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach assert (Done && "Unable to resolve frame index!"); 10661f6a329f79b3568d379142f921f59c4143ddaa14Duncan Sands (void)Done; 1067dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach} 10688708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach 1069e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbachbool ARMBaseRegisterInfo::isFrameOffsetLegal(const MachineInstr *MI, 1070e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach int64_t Offset) const { 1071e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng const MCInstrDesc &Desc = MI->getDesc(); 10722b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); 10732b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach unsigned i = 0; 10742b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach 10752b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach while (!MI->getOperand(i).isFI()) { 10762b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach ++i; 10772b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach assert(i < MI->getNumOperands() &&"Instr doesn't have FrameIndex operand!"); 10782b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach } 10792b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach 10802b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach // AddrMode4 and AddrMode6 cannot handle any offset. 10812b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach if (AddrMode == ARMII::AddrMode4 || AddrMode == ARMII::AddrMode6) 10822b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach return Offset == 0; 10832b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach 10842b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach unsigned NumBits = 0; 10852b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach unsigned Scale = 1; 1086e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach bool isSigned = true; 10871ab3f16f06698596716593a30545799688acccd7Jim Grosbach switch (AddrMode) { 10882b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach case ARMII::AddrModeT2_i8: 10892b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach case ARMII::AddrModeT2_i12: 10902b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach // i8 supports only negative, and i12 supports only positive, so 10912b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach // based on Offset sign, consider the appropriate instruction 109274d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach Scale = 1; 10932b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach if (Offset < 0) { 10942b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach NumBits = 8; 10952b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach Offset = -Offset; 10962b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach } else { 10972b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach NumBits = 12; 10982b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach } 10992b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach break; 11001ab3f16f06698596716593a30545799688acccd7Jim Grosbach case ARMII::AddrMode5: 11012b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach // VFP address mode. 11022b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach NumBits = 8; 11032b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach Scale = 4; 11042b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach break; 11053e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach case ARMII::AddrMode_i12: 11061ab3f16f06698596716593a30545799688acccd7Jim Grosbach case ARMII::AddrMode2: 11072b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach NumBits = 12; 11082b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach break; 11091ab3f16f06698596716593a30545799688acccd7Jim Grosbach case ARMII::AddrMode3: 11102b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach NumBits = 8; 11112b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach break; 1112e575499d830008784b11499dae290ad0480c8f9dBill Wendling case ARMII::AddrModeT1_s: 1113e575499d830008784b11499dae290ad0480c8f9dBill Wendling NumBits = 5; 111474d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach Scale = 4; 1115e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach isSigned = false; 111674d7b0af58951dce2f874c600a6a48a2454b4914Jim Grosbach break; 11172b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach default: 11182b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach llvm_unreachable("Unsupported addressing mode!"); 11192b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach break; 11202b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach } 11212b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach 11221ab3f16f06698596716593a30545799688acccd7Jim Grosbach Offset += getFrameIndexInstrOffset(MI, i); 1123d4511e947ee1e89a4f199bfac0d401976930ccfeJim Grosbach // Make sure the offset is encodable for instructions that scale the 1124d4511e947ee1e89a4f199bfac0d401976930ccfeJim Grosbach // immediate. 1125d4511e947ee1e89a4f199bfac0d401976930ccfeJim Grosbach if ((Offset & (Scale-1)) != 0) 1126d4511e947ee1e89a4f199bfac0d401976930ccfeJim Grosbach return false; 1127d4511e947ee1e89a4f199bfac0d401976930ccfeJim Grosbach 1128e2f556933e1a19cddf6d4f370e2770c0f763b025Jim Grosbach if (isSigned && Offset < 0) 11292b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach Offset = -Offset; 11302b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach 11312b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach unsigned Mask = (1 << NumBits) - 1; 11322b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach if ((unsigned)Offset <= Mask * Scale) 11332b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach return true; 113474d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach 113574d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach return false; 113674d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach} 113774d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach 1138fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbachvoid 11396495f63945e8dbde81f03a1dc2ab421993b9a495Evan ChengARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 1140fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach int SPAdj, RegScavenger *RS) const { 11415ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin unsigned i = 0; 11425ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin MachineInstr &MI = *II; 11435ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin MachineBasicBlock &MBB = *MI.getParent(); 11445ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin MachineFunction &MF = *MBB.getParent(); 114516c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const ARMFrameLowering *TFI = 114616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov static_cast<const ARMFrameLowering*>(MF.getTarget().getFrameLowering()); 11475ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 11486495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng assert(!AFI->isThumb1OnlyFunction() && 1149a15de00f8246f19180b26ee5fe7ff8f436e0de08Bob Wilson "This eliminateFrameIndex does not support Thumb1!"); 11505ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin 11515ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin while (!MI.getOperand(i).isFI()) { 11525ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin ++i; 11535ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 11545ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin } 11555ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin 11565ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin int FrameIndex = MI.getOperand(i).getIndex(); 1157a37aa546224ec03ba1f1a1598e0781af4b692673Jim Grosbach unsigned FrameReg; 11585ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin 115982f58740c76b42af8370247b23677a0318f6dde8Anton Korobeynikov int Offset = TFI->ResolveFrameIndexReference(MF, FrameIndex, FrameReg, SPAdj); 11605ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin 116162b50656ceb854eb0be265d63b2a1d46e7400d8aEvan Cheng // Special handling of dbg_value instructions. 116262b50656ceb854eb0be265d63b2a1d46e7400d8aEvan Cheng if (MI.isDebugValue()) { 116362b50656ceb854eb0be265d63b2a1d46e7400d8aEvan Cheng MI.getOperand(i). ChangeToRegister(FrameReg, false /*isDef*/); 116462b50656ceb854eb0be265d63b2a1d46e7400d8aEvan Cheng MI.getOperand(i+1).ChangeToImmediate(Offset); 1165fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach return; 116662b50656ceb854eb0be265d63b2a1d46e7400d8aEvan Cheng } 116762b50656ceb854eb0be265d63b2a1d46e7400d8aEvan Cheng 116848d8afab73d72418cf9505a020f621014920463cEvan Cheng // Modify MI as necessary to handle as much of 'Offset' as possible 1169cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng bool Done = false; 11706495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng if (!AFI->isThumbFunction()) 1171cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng Done = rewriteARMFrameIndex(MI, i, FrameReg, Offset, TII); 11726495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng else { 11736495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng assert(AFI->isThumb2Function()); 1174cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng Done = rewriteT2FrameIndex(MI, i, FrameReg, Offset, TII); 11756495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } 1176cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng if (Done) 1177fcb4a8ead3cd8d9540d5eaa448af5d14a0ee341aJim Grosbach return; 11785ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin 1179db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin // If we get here, the immediate doesn't fit into the instruction. We folded 1180db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin // as much as possible above, handle the rest, providing a register that is 1181db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin // SP+LargeImm. 118219bb87d0f80f3e6eed38a9fa267bf2b0474aeaabDaniel Dunbar assert((Offset || 1183a44321776ecd96fa0344335d3027758be3386e45Jim Grosbach (MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrMode4 || 1184a44321776ecd96fa0344335d3027758be3386e45Jim Grosbach (MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrMode6) && 1185cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng "This code isn't needed if offset already handled!"); 1186db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin 11877e831db1d4f5dc51ca6526739cf41e59895c5c20Jim Grosbach unsigned ScratchReg = 0; 1188db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin int PIdx = MI.findFirstPredOperandIdx(); 1189db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin ARMCC::CondCodes Pred = (PIdx == -1) 1190db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin ? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(PIdx).getImm(); 1191db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin unsigned PredReg = (PIdx == -1) ? 0 : MI.getOperand(PIdx+1).getReg(); 1192cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng if (Offset == 0) 1193a44321776ecd96fa0344335d3027758be3386e45Jim Grosbach // Must be addrmode4/6. 1194cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng MI.getOperand(i).ChangeToRegister(FrameReg, false, false, false); 11956495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng else { 1196ca5dfb71ba4aa4a8392a021ec056cf0b70f74f1eJim Grosbach ScratchReg = MF.getRegInfo().createVirtualRegister(ARM::GPRRegisterClass); 1197cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng if (!AFI->isThumbFunction()) 1198cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng emitARMRegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg, 1199cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng Offset, Pred, PredReg, TII); 1200cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng else { 1201cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng assert(AFI->isThumb2Function()); 1202cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng emitT2RegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg, 1203cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng Offset, Pred, PredReg, TII); 1204cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng } 1205cde31293d45f14ddff482d385429d256bd4e0820Jim Grosbach // Update the original instruction to use the scratch register. 1206cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true); 12076495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng } 1208db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin} 1209