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