Thumb1InstrInfo.cpp revision ac2736670034e8942939b9fccf8e4618a0bda908
1//===- Thumb1InstrInfo.cpp - Thumb-1 Instruction Information ----*- C++ -*-===// 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 Thumb-1 implementation of the TargetInstrInfo class. 11// 12//===----------------------------------------------------------------------===// 13 14#include "Thumb1InstrInfo.h" 15#include "ARM.h" 16#include "ARMGenInstrInfo.inc" 17#include "ARMMachineFunctionInfo.h" 18#include "llvm/CodeGen/MachineFrameInfo.h" 19#include "llvm/CodeGen/MachineInstrBuilder.h" 20#include "llvm/CodeGen/MachineRegisterInfo.h" 21#include "llvm/CodeGen/MachineMemOperand.h" 22#include "llvm/CodeGen/PseudoSourceValue.h" 23#include "llvm/ADT/SmallVector.h" 24#include "Thumb1InstrInfo.h" 25 26using namespace llvm; 27 28Thumb1InstrInfo::Thumb1InstrInfo(const ARMSubtarget &STI) 29 : ARMBaseInstrInfo(STI), RI(*this, STI) { 30} 31 32unsigned Thumb1InstrInfo::getUnindexedOpcode(unsigned Opc) const { 33 return 0; 34} 35 36void Thumb1InstrInfo::copyPhysReg(MachineBasicBlock &MBB, 37 MachineBasicBlock::iterator I, DebugLoc DL, 38 unsigned DestReg, unsigned SrcReg, 39 bool KillSrc) const { 40 bool tDest = ARM::tGPRRegClass.contains(DestReg); 41 bool tSrc = ARM::tGPRRegClass.contains(SrcReg); 42 unsigned Opc = ARM::tMOVgpr2gpr; 43 if (tDest && tSrc) 44 Opc = ARM::tMOVr; 45 else if (tSrc) 46 Opc = ARM::tMOVtgpr2gpr; 47 else if (tDest) 48 Opc = ARM::tMOVgpr2tgpr; 49 50 BuildMI(MBB, I, DL, get(Opc), DestReg) 51 .addReg(SrcReg, getKillRegState(KillSrc)); 52 assert(ARM::GPRRegClass.contains(DestReg, SrcReg) && 53 "Thumb1 can only copy GPR registers"); 54} 55 56bool Thumb1InstrInfo:: 57canFoldMemoryOperand(const MachineInstr *MI, 58 const SmallVectorImpl<unsigned> &Ops) const { 59 if (Ops.size() != 1) return false; 60 61 unsigned OpNum = Ops[0]; 62 unsigned Opc = MI->getOpcode(); 63 switch (Opc) { 64 default: break; 65 case ARM::tMOVr: 66 case ARM::tMOVtgpr2gpr: 67 case ARM::tMOVgpr2tgpr: 68 case ARM::tMOVgpr2gpr: { 69 if (OpNum == 0) { // move -> store 70 unsigned SrcReg = MI->getOperand(1).getReg(); 71 if (TargetRegisterInfo::isPhysicalRegister(SrcReg) && 72 !isARMLowRegister(SrcReg)) 73 // tSpill cannot take a high register operand. 74 return false; 75 } else { // move -> load 76 unsigned DstReg = MI->getOperand(0).getReg(); 77 if (TargetRegisterInfo::isPhysicalRegister(DstReg) && 78 !isARMLowRegister(DstReg)) 79 // tRestore cannot target a high register operand. 80 return false; 81 } 82 return true; 83 } 84 } 85 86 return false; 87} 88 89void Thumb1InstrInfo:: 90storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 91 unsigned SrcReg, bool isKill, int FI, 92 const TargetRegisterClass *RC, 93 const TargetRegisterInfo *TRI) const { 94 assert((RC == ARM::tGPRRegisterClass || 95 (TargetRegisterInfo::isPhysicalRegister(SrcReg) && 96 isARMLowRegister(SrcReg))) && "Unknown regclass!"); 97 98 if (RC == ARM::tGPRRegisterClass || 99 (TargetRegisterInfo::isPhysicalRegister(SrcReg) && 100 isARMLowRegister(SrcReg))) { 101 DebugLoc DL; 102 if (I != MBB.end()) DL = I->getDebugLoc(); 103 104 MachineFunction &MF = *MBB.getParent(); 105 MachineFrameInfo &MFI = *MF.getFrameInfo(); 106 MachineMemOperand *MMO = 107 MF.getMachineMemOperand(PseudoSourceValue::getFixedStack(FI), 108 MachineMemOperand::MOStore, 0, 109 MFI.getObjectSize(FI), 110 MFI.getObjectAlignment(FI)); 111 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::tSpill)) 112 .addReg(SrcReg, getKillRegState(isKill)) 113 .addFrameIndex(FI).addImm(0).addMemOperand(MMO)); 114 } 115} 116 117void Thumb1InstrInfo:: 118loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 119 unsigned DestReg, int FI, 120 const TargetRegisterClass *RC, 121 const TargetRegisterInfo *TRI) const { 122 assert((RC == ARM::tGPRRegisterClass || 123 (TargetRegisterInfo::isPhysicalRegister(DestReg) && 124 isARMLowRegister(DestReg))) && "Unknown regclass!"); 125 126 if (RC == ARM::tGPRRegisterClass || 127 (TargetRegisterInfo::isPhysicalRegister(DestReg) && 128 isARMLowRegister(DestReg))) { 129 DebugLoc DL; 130 if (I != MBB.end()) DL = I->getDebugLoc(); 131 132 MachineFunction &MF = *MBB.getParent(); 133 MachineFrameInfo &MFI = *MF.getFrameInfo(); 134 MachineMemOperand *MMO = 135 MF.getMachineMemOperand(PseudoSourceValue::getFixedStack(FI), 136 MachineMemOperand::MOLoad, 0, 137 MFI.getObjectSize(FI), 138 MFI.getObjectAlignment(FI)); 139 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::tRestore), DestReg) 140 .addFrameIndex(FI).addImm(0).addMemOperand(MMO)); 141 } 142} 143 144bool Thumb1InstrInfo:: 145spillCalleeSavedRegisters(MachineBasicBlock &MBB, 146 MachineBasicBlock::iterator MI, 147 const std::vector<CalleeSavedInfo> &CSI, 148 const TargetRegisterInfo *TRI) const { 149 if (CSI.empty()) 150 return false; 151 152 DebugLoc DL; 153 if (MI != MBB.end()) DL = MI->getDebugLoc(); 154 155 MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, get(ARM::tPUSH)); 156 AddDefaultPred(MIB); 157 for (unsigned i = CSI.size(); i != 0; --i) { 158 unsigned Reg = CSI[i-1].getReg(); 159 bool isKill = true; 160 161 // Add the callee-saved register as live-in unless it's LR and 162 // @llvm.returnaddress is called. If LR is returned for @llvm.returnaddress 163 // then it's already added to the function and entry block live-in sets. 164 if (Reg == ARM::LR) { 165 MachineFunction &MF = *MBB.getParent(); 166 if (MF.getFrameInfo()->isReturnAddressTaken() && 167 MF.getRegInfo().isLiveIn(Reg)) 168 isKill = false; 169 } 170 171 if (isKill) 172 MBB.addLiveIn(Reg); 173 174 MIB.addReg(Reg, getKillRegState(isKill)); 175 } 176 return true; 177} 178 179bool Thumb1InstrInfo:: 180restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 181 MachineBasicBlock::iterator MI, 182 const std::vector<CalleeSavedInfo> &CSI, 183 const TargetRegisterInfo *TRI) const { 184 MachineFunction &MF = *MBB.getParent(); 185 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 186 if (CSI.empty()) 187 return false; 188 189 bool isVarArg = AFI->getVarArgsRegSaveSize() > 0; 190 DebugLoc DL = MI->getDebugLoc(); 191 MachineInstrBuilder MIB = BuildMI(MF, DL, get(ARM::tPOP)); 192 AddDefaultPred(MIB); 193 194 bool NumRegs = false; 195 for (unsigned i = CSI.size(); i != 0; --i) { 196 unsigned Reg = CSI[i-1].getReg(); 197 if (Reg == ARM::LR) { 198 // Special epilogue for vararg functions. See emitEpilogue 199 if (isVarArg) 200 continue; 201 Reg = ARM::PC; 202 (*MIB).setDesc(get(ARM::tPOP_RET)); 203 MI = MBB.erase(MI); 204 } 205 MIB.addReg(Reg, getDefRegState(true)); 206 NumRegs = true; 207 } 208 209 // It's illegal to emit pop instruction without operands. 210 if (NumRegs) 211 MBB.insert(MI, &*MIB); 212 else 213 MF.DeleteMachineInstr(MIB); 214 215 return true; 216} 217 218MachineInstr *Thumb1InstrInfo:: 219foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, 220 const SmallVectorImpl<unsigned> &Ops, int FI) const { 221 if (Ops.size() != 1) return NULL; 222 223 unsigned OpNum = Ops[0]; 224 unsigned Opc = MI->getOpcode(); 225 MachineInstr *NewMI = NULL; 226 switch (Opc) { 227 default: break; 228 case ARM::tMOVr: 229 case ARM::tMOVtgpr2gpr: 230 case ARM::tMOVgpr2tgpr: 231 case ARM::tMOVgpr2gpr: { 232 if (OpNum == 0) { // move -> store 233 unsigned SrcReg = MI->getOperand(1).getReg(); 234 bool isKill = MI->getOperand(1).isKill(); 235 if (TargetRegisterInfo::isPhysicalRegister(SrcReg) && 236 !isARMLowRegister(SrcReg)) 237 // tSpill cannot take a high register operand. 238 break; 239 NewMI = AddDefaultPred(BuildMI(MF, MI->getDebugLoc(), get(ARM::tSpill)) 240 .addReg(SrcReg, getKillRegState(isKill)) 241 .addFrameIndex(FI).addImm(0)); 242 } else { // move -> load 243 unsigned DstReg = MI->getOperand(0).getReg(); 244 if (TargetRegisterInfo::isPhysicalRegister(DstReg) && 245 !isARMLowRegister(DstReg)) 246 // tRestore cannot target a high register operand. 247 break; 248 bool isDead = MI->getOperand(0).isDead(); 249 NewMI = AddDefaultPred(BuildMI(MF, MI->getDebugLoc(), get(ARM::tRestore)) 250 .addReg(DstReg, 251 RegState::Define | getDeadRegState(isDead)) 252 .addFrameIndex(FI).addImm(0)); 253 } 254 break; 255 } 256 } 257 258 return NewMI; 259} 260