1 //===-- ARMInstrInfo.cpp - ARM Instruction Information --------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains the ARM implementation of the TargetInstrInfo class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "ARMInstrInfo.h" 15 #include "ARM.h" 16 #include "ARMConstantPoolValue.h" 17 #include "ARMMachineFunctionInfo.h" 18 #include "ARMTargetMachine.h" 19 #include "MCTargetDesc/ARMAddressingModes.h" 20 #include "llvm/ADT/STLExtras.h" 21 #include "llvm/CodeGen/LiveVariables.h" 22 #include "llvm/CodeGen/MachineFrameInfo.h" 23 #include "llvm/CodeGen/MachineInstrBuilder.h" 24 #include "llvm/CodeGen/MachineJumpTableInfo.h" 25 #include "llvm/CodeGen/MachineRegisterInfo.h" 26 #include "llvm/IR/Function.h" 27 #include "llvm/IR/GlobalVariable.h" 28 #include "llvm/MC/MCAsmInfo.h" 29 #include "llvm/MC/MCInst.h" 30 using namespace llvm; 31 32 ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI) 33 : ARMBaseInstrInfo(STI), RI() {} 34 35 /// getNoopForMachoTarget - Return the noop instruction to use for a noop. 36 void ARMInstrInfo::getNoopForMachoTarget(MCInst &NopInst) const { 37 if (hasNOP()) { 38 NopInst.setOpcode(ARM::HINT); 39 NopInst.addOperand(MCOperand::createImm(0)); 40 NopInst.addOperand(MCOperand::createImm(ARMCC::AL)); 41 NopInst.addOperand(MCOperand::createReg(0)); 42 } else { 43 NopInst.setOpcode(ARM::MOVr); 44 NopInst.addOperand(MCOperand::createReg(ARM::R0)); 45 NopInst.addOperand(MCOperand::createReg(ARM::R0)); 46 NopInst.addOperand(MCOperand::createImm(ARMCC::AL)); 47 NopInst.addOperand(MCOperand::createReg(0)); 48 NopInst.addOperand(MCOperand::createReg(0)); 49 } 50 } 51 52 unsigned ARMInstrInfo::getUnindexedOpcode(unsigned Opc) const { 53 switch (Opc) { 54 default: 55 break; 56 case ARM::LDR_PRE_IMM: 57 case ARM::LDR_PRE_REG: 58 case ARM::LDR_POST_IMM: 59 case ARM::LDR_POST_REG: 60 return ARM::LDRi12; 61 case ARM::LDRH_PRE: 62 case ARM::LDRH_POST: 63 return ARM::LDRH; 64 case ARM::LDRB_PRE_IMM: 65 case ARM::LDRB_PRE_REG: 66 case ARM::LDRB_POST_IMM: 67 case ARM::LDRB_POST_REG: 68 return ARM::LDRBi12; 69 case ARM::LDRSH_PRE: 70 case ARM::LDRSH_POST: 71 return ARM::LDRSH; 72 case ARM::LDRSB_PRE: 73 case ARM::LDRSB_POST: 74 return ARM::LDRSB; 75 case ARM::STR_PRE_IMM: 76 case ARM::STR_PRE_REG: 77 case ARM::STR_POST_IMM: 78 case ARM::STR_POST_REG: 79 return ARM::STRi12; 80 case ARM::STRH_PRE: 81 case ARM::STRH_POST: 82 return ARM::STRH; 83 case ARM::STRB_PRE_IMM: 84 case ARM::STRB_PRE_REG: 85 case ARM::STRB_POST_IMM: 86 case ARM::STRB_POST_REG: 87 return ARM::STRBi12; 88 } 89 90 return 0; 91 } 92 93 void ARMInstrInfo::expandLoadStackGuard(MachineBasicBlock::iterator MI, 94 Reloc::Model RM) const { 95 MachineFunction &MF = *MI->getParent()->getParent(); 96 const ARMSubtarget &Subtarget = MF.getSubtarget<ARMSubtarget>(); 97 98 if (!Subtarget.useMovt(MF)) { 99 if (RM == Reloc::PIC_) 100 expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_pcrel, ARM::LDRi12, RM); 101 else 102 expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_abs, ARM::LDRi12, RM); 103 return; 104 } 105 106 if (RM != Reloc::PIC_) { 107 expandLoadStackGuardBase(MI, ARM::MOVi32imm, ARM::LDRi12, RM); 108 return; 109 } 110 111 const GlobalValue *GV = 112 cast<GlobalValue>((*MI->memoperands_begin())->getValue()); 113 114 if (!Subtarget.GVIsIndirectSymbol(GV, RM)) { 115 expandLoadStackGuardBase(MI, ARM::MOV_ga_pcrel, ARM::LDRi12, RM); 116 return; 117 } 118 119 MachineBasicBlock &MBB = *MI->getParent(); 120 DebugLoc DL = MI->getDebugLoc(); 121 unsigned Reg = MI->getOperand(0).getReg(); 122 MachineInstrBuilder MIB; 123 124 MIB = BuildMI(MBB, MI, DL, get(ARM::MOV_ga_pcrel_ldr), Reg) 125 .addGlobalAddress(GV, 0, ARMII::MO_NONLAZY); 126 unsigned Flag = MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant; 127 MachineMemOperand *MMO = MBB.getParent()->getMachineMemOperand( 128 MachinePointerInfo::getGOT(*MBB.getParent()), Flag, 4, 4); 129 MIB.addMemOperand(MMO); 130 MIB = BuildMI(MBB, MI, DL, get(ARM::LDRi12), Reg); 131 MIB.addReg(Reg, RegState::Kill).addImm(0); 132 MIB.setMemRefs(MI->memoperands_begin(), MI->memoperands_end()); 133 AddDefaultPred(MIB); 134 } 135