131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- ARMInstrInfo.cpp - ARM Instruction Information --------------------===//
27bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
37bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//                     The LLVM Compiler Infrastructure
47bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
67bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// License. See LICENSE.TXT for details.
77bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
87bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//===----------------------------------------------------------------------===//
97bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
107bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// This file contains the ARM implementation of the TargetInstrInfo class.
117bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
127bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//===----------------------------------------------------------------------===//
137bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
147bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARMInstrInfo.h"
157bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARM.h"
168f50647662560167b88851f92c3c891d2e7c1696Jush Lu#include "ARMConstantPoolValue.h"
17a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMMachineFunctionInfo.h"
188f50647662560167b88851f92c3c891d2e7c1696Jush Lu#include "ARMTargetMachine.h"
19ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h"
20718cb665ca6ce2bc4d8e8479f46a45db91b49f86Owen Anderson#include "llvm/ADT/STLExtras.h"
21a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/CodeGen/LiveVariables.h"
22d94b6a16fec7d5021e3922b0e34f9ddb268d54b1Owen Anderson#include "llvm/CodeGen/MachineFrameInfo.h"
2329836c330ff33e3c6a250a89b3e78abb3a1970c9Evan Cheng#include "llvm/CodeGen/MachineInstrBuilder.h"
2429836c330ff33e3c6a250a89b3e78abb3a1970c9Evan Cheng#include "llvm/CodeGen/MachineJumpTableInfo.h"
250b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h"
260b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/GlobalVariable.h"
27af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner#include "llvm/MC/MCAsmInfo.h"
28c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbach#include "llvm/MC/MCInst.h"
297bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolausing namespace llvm;
307bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
31d49ea77cbc24776142615fecf75f41e191c765bdAnton KorobeynikovARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI)
3257148c166ab232191098492633c924fad9c44ef3Bill Wendling  : ARMBaseInstrInfo(STI), RI(STI) {
33d49ea77cbc24776142615fecf75f41e191c765bdAnton Korobeynikov}
3446adf8119df362bfed7c6d71dd467527981b97daRafael Espindola
35c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbach/// getNoopForMachoTarget - Return the noop instruction to use for a noop.
36c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbachvoid ARMInstrInfo::getNoopForMachoTarget(MCInst &NopInst) const {
37c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbach  if (hasNOP()) {
387e99a60857532ca2973cf9dabc790d84a2e15a8aJim Grosbach    NopInst.setOpcode(ARM::HINT);
397e99a60857532ca2973cf9dabc790d84a2e15a8aJim Grosbach    NopInst.addOperand(MCOperand::CreateImm(0));
40c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbach    NopInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
41c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbach    NopInst.addOperand(MCOperand::CreateReg(0));
42c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbach  } else {
43c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbach    NopInst.setOpcode(ARM::MOVr);
44c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbach    NopInst.addOperand(MCOperand::CreateReg(ARM::R0));
45c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbach    NopInst.addOperand(MCOperand::CreateReg(ARM::R0));
46c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbach    NopInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
47c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbach    NopInst.addOperand(MCOperand::CreateReg(0));
48c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbach    NopInst.addOperand(MCOperand::CreateReg(0));
49c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbach  }
50c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbach}
51c01810eeb7227010f73cb39e3c4fa0197a3c4ef0Jim Grosbach
52d90183d25dcbc0eabde56319fed4e8d6ace2e6ebChris Lattnerunsigned ARMInstrInfo::getUnindexedOpcode(unsigned Opc) const {
53a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  switch (Opc) {
54a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  default: break;
559ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  case ARM::LDR_PRE_IMM:
569ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  case ARM::LDR_PRE_REG:
57793e79601f0fd68ba082fa2016018f80b2379460Owen Anderson  case ARM::LDR_POST_IMM:
58793e79601f0fd68ba082fa2016018f80b2379460Owen Anderson  case ARM::LDR_POST_REG:
593e5561247202bae994dd259a2d8dc4eff8f799f3Jim Grosbach    return ARM::LDRi12;
60a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case ARM::LDRH_PRE:
61a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case ARM::LDRH_POST:
62a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return ARM::LDRH;
639ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  case ARM::LDRB_PRE_IMM:
649ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  case ARM::LDRB_PRE_REG:
65793e79601f0fd68ba082fa2016018f80b2379460Owen Anderson  case ARM::LDRB_POST_IMM:
66793e79601f0fd68ba082fa2016018f80b2379460Owen Anderson  case ARM::LDRB_POST_REG:
67c1d30212e911d1e55ff6b25bffefb503708883c3Jim Grosbach    return ARM::LDRBi12;
68a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case ARM::LDRSH_PRE:
69a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case ARM::LDRSH_POST:
70a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return ARM::LDRSH;
71a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case ARM::LDRSB_PRE:
72a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case ARM::LDRSB_POST:
73a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return ARM::LDRSB;
74793e79601f0fd68ba082fa2016018f80b2379460Owen Anderson  case ARM::STR_PRE_IMM:
75793e79601f0fd68ba082fa2016018f80b2379460Owen Anderson  case ARM::STR_PRE_REG:
76793e79601f0fd68ba082fa2016018f80b2379460Owen Anderson  case ARM::STR_POST_IMM:
77793e79601f0fd68ba082fa2016018f80b2379460Owen Anderson  case ARM::STR_POST_REG:
787e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach    return ARM::STRi12;
79a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case ARM::STRH_PRE:
80a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case ARM::STRH_POST:
81a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return ARM::STRH;
82793e79601f0fd68ba082fa2016018f80b2379460Owen Anderson  case ARM::STRB_PRE_IMM:
83793e79601f0fd68ba082fa2016018f80b2379460Owen Anderson  case ARM::STRB_PRE_REG:
84793e79601f0fd68ba082fa2016018f80b2379460Owen Anderson  case ARM::STRB_POST_IMM:
85793e79601f0fd68ba082fa2016018f80b2379460Owen Anderson  case ARM::STRB_POST_REG:
867e3383c007f53b3a00675af225e428cb66ddf404Jim Grosbach    return ARM::STRBi12;
873ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola  }
88334c26473bba3ad8b88341bb0d25d0ac2008bb8dDavid Goodwin
89a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  return 0;
907bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
918f50647662560167b88851f92c3c891d2e7c1696Jush Lu
928f50647662560167b88851f92c3c891d2e7c1696Jush Lunamespace {
938f50647662560167b88851f92c3c891d2e7c1696Jush Lu  /// ARMCGBR - Create Global Base Reg pass. This initializes the PIC
948f50647662560167b88851f92c3c891d2e7c1696Jush Lu  /// global base register for ARM ELF.
958f50647662560167b88851f92c3c891d2e7c1696Jush Lu  struct ARMCGBR : public MachineFunctionPass {
968f50647662560167b88851f92c3c891d2e7c1696Jush Lu    static char ID;
978f50647662560167b88851f92c3c891d2e7c1696Jush Lu    ARMCGBR() : MachineFunctionPass(ID) {}
988f50647662560167b88851f92c3c891d2e7c1696Jush Lu
998f50647662560167b88851f92c3c891d2e7c1696Jush Lu    virtual bool runOnMachineFunction(MachineFunction &MF) {
1008f50647662560167b88851f92c3c891d2e7c1696Jush Lu      ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
1018f50647662560167b88851f92c3c891d2e7c1696Jush Lu      if (AFI->getGlobalBaseReg() == 0)
1028f50647662560167b88851f92c3c891d2e7c1696Jush Lu        return false;
1038f50647662560167b88851f92c3c891d2e7c1696Jush Lu
1048f50647662560167b88851f92c3c891d2e7c1696Jush Lu      const ARMTargetMachine *TM =
1058f50647662560167b88851f92c3c891d2e7c1696Jush Lu        static_cast<const ARMTargetMachine *>(&MF.getTarget());
1068f50647662560167b88851f92c3c891d2e7c1696Jush Lu      if (TM->getRelocationModel() != Reloc::PIC_)
1078f50647662560167b88851f92c3c891d2e7c1696Jush Lu        return false;
1088f50647662560167b88851f92c3c891d2e7c1696Jush Lu
109214de30d9d3739bb384188720aa6c389edcf89dcChandler Carruth      LLVMContext *Context = &MF.getFunction()->getContext();
110214de30d9d3739bb384188720aa6c389edcf89dcChandler Carruth      unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
111214de30d9d3739bb384188720aa6c389edcf89dcChandler Carruth      unsigned PCAdj = TM->getSubtarget<ARMSubtarget>().isThumb() ? 4 : 8;
112214de30d9d3739bb384188720aa6c389edcf89dcChandler Carruth      ARMConstantPoolValue *CPV = ARMConstantPoolSymbol::Create(
113214de30d9d3739bb384188720aa6c389edcf89dcChandler Carruth          *Context, "_GLOBAL_OFFSET_TABLE_", ARMPCLabelIndex, PCAdj);
114214de30d9d3739bb384188720aa6c389edcf89dcChandler Carruth
115214de30d9d3739bb384188720aa6c389edcf89dcChandler Carruth      unsigned Align = TM->getDataLayout()
116214de30d9d3739bb384188720aa6c389edcf89dcChandler Carruth          ->getPrefTypeAlignment(Type::getInt32PtrTy(*Context));
1178f50647662560167b88851f92c3c891d2e7c1696Jush Lu      unsigned Idx = MF.getConstantPool()->getConstantPoolIndex(CPV, Align);
1188f50647662560167b88851f92c3c891d2e7c1696Jush Lu
1198f50647662560167b88851f92c3c891d2e7c1696Jush Lu      MachineBasicBlock &FirstMBB = MF.front();
1208f50647662560167b88851f92c3c891d2e7c1696Jush Lu      MachineBasicBlock::iterator MBBI = FirstMBB.begin();
1218f50647662560167b88851f92c3c891d2e7c1696Jush Lu      DebugLoc DL = FirstMBB.findDebugLoc(MBBI);
1228f50647662560167b88851f92c3c891d2e7c1696Jush Lu      unsigned GlobalBaseReg = AFI->getGlobalBaseReg();
1238f50647662560167b88851f92c3c891d2e7c1696Jush Lu      unsigned Opc = TM->getSubtarget<ARMSubtarget>().isThumb2() ?
1248f50647662560167b88851f92c3c891d2e7c1696Jush Lu                     ARM::t2LDRpci : ARM::LDRcp;
1258f50647662560167b88851f92c3c891d2e7c1696Jush Lu      const TargetInstrInfo &TII = *TM->getInstrInfo();
1268f50647662560167b88851f92c3c891d2e7c1696Jush Lu      MachineInstrBuilder MIB = BuildMI(FirstMBB, MBBI, DL,
1278f50647662560167b88851f92c3c891d2e7c1696Jush Lu                                        TII.get(Opc), GlobalBaseReg)
1288f50647662560167b88851f92c3c891d2e7c1696Jush Lu                                .addConstantPoolIndex(Idx);
1298f50647662560167b88851f92c3c891d2e7c1696Jush Lu      if (Opc == ARM::LDRcp)
1308f50647662560167b88851f92c3c891d2e7c1696Jush Lu        MIB.addImm(0);
1318f50647662560167b88851f92c3c891d2e7c1696Jush Lu      AddDefaultPred(MIB);
1328f50647662560167b88851f92c3c891d2e7c1696Jush Lu
1338f50647662560167b88851f92c3c891d2e7c1696Jush Lu      return true;
1348f50647662560167b88851f92c3c891d2e7c1696Jush Lu    }
1358f50647662560167b88851f92c3c891d2e7c1696Jush Lu
1368f50647662560167b88851f92c3c891d2e7c1696Jush Lu    virtual const char *getPassName() const {
1378f50647662560167b88851f92c3c891d2e7c1696Jush Lu      return "ARM PIC Global Base Reg Initialization";
1388f50647662560167b88851f92c3c891d2e7c1696Jush Lu    }
1398f50647662560167b88851f92c3c891d2e7c1696Jush Lu
1408f50647662560167b88851f92c3c891d2e7c1696Jush Lu    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
1418f50647662560167b88851f92c3c891d2e7c1696Jush Lu      AU.setPreservesCFG();
1428f50647662560167b88851f92c3c891d2e7c1696Jush Lu      MachineFunctionPass::getAnalysisUsage(AU);
1438f50647662560167b88851f92c3c891d2e7c1696Jush Lu    }
1448f50647662560167b88851f92c3c891d2e7c1696Jush Lu  };
1458f50647662560167b88851f92c3c891d2e7c1696Jush Lu}
1468f50647662560167b88851f92c3c891d2e7c1696Jush Lu
1478f50647662560167b88851f92c3c891d2e7c1696Jush Luchar ARMCGBR::ID = 0;
1488f50647662560167b88851f92c3c891d2e7c1696Jush LuFunctionPass*
1498f50647662560167b88851f92c3c891d2e7c1696Jush Lullvm::createARMGlobalBaseRegPass() { return new ARMCGBR(); }
150