Thumb1InstrInfo.cpp revision 5732ca084aaa0cd26149e50dd4b487efff37fe41
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 "ARMInstrInfo.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/ADT/SmallVector.h" 21#include "Thumb1InstrInfo.h" 22 23using namespace llvm; 24 25Thumb1InstrInfo::Thumb1InstrInfo(const ARMSubtarget &STI) 26 : ARMBaseInstrInfo(STI), RI(*this, STI) { 27} 28 29unsigned Thumb1InstrInfo::getUnindexedOpcode(unsigned Opc) const { 30 return 0; 31} 32 33unsigned Thumb1InstrInfo::getOpcode(ARMII::Op Op) const { 34 switch (Op) { 35 case ARMII::ADDri: return ARM::tADDi8; 36 case ARMII::ADDrs: return 0; 37 case ARMII::ADDrr: return ARM::tADDrr; 38 case ARMII::B: return ARM::tB; 39 case ARMII::Bcc: return ARM::tBcc; 40 case ARMII::BX_RET: return ARM::tBX_RET; 41 case ARMII::LDRri: return 0; 42 case ARMII::MOVr: return ARM::tMOVr; 43 case ARMII::STRri: return 0; 44 case ARMII::SUBri: return ARM::tSUBi8; 45 case ARMII::SUBrs: return 0; 46 case ARMII::SUBrr: return ARM::tSUBrr; 47 default: 48 break; 49 } 50 51 return 0; 52} 53 54bool 55Thumb1InstrInfo::BlockHasNoFallThrough(const MachineBasicBlock &MBB) const { 56 if (MBB.empty()) return false; 57 58 switch (MBB.back().getOpcode()) { 59 case ARM::tBX_RET: 60 case ARM::tBX_RET_vararg: 61 case ARM::tPOP_RET: 62 case ARM::tB: 63 case ARM::tBR_JTr: 64 return true; 65 default: 66 break; 67 } 68 69 return false; 70} 71 72bool Thumb1InstrInfo::copyRegToReg(MachineBasicBlock &MBB, 73 MachineBasicBlock::iterator I, 74 unsigned DestReg, unsigned SrcReg, 75 const TargetRegisterClass *DestRC, 76 const TargetRegisterClass *SrcRC) const { 77 DebugLoc DL = DebugLoc::getUnknownLoc(); 78 if (I != MBB.end()) DL = I->getDebugLoc(); 79 80 if (DestRC == ARM::GPRRegisterClass) { 81 if (SrcRC == ARM::GPRRegisterClass) { 82 BuildMI(MBB, I, DL, get(ARM::tMOVgpr2gpr), DestReg).addReg(SrcReg); 83 return true; 84 } else if (SrcRC == ARM::tGPRRegisterClass) { 85 BuildMI(MBB, I, DL, get(ARM::tMOVtgpr2gpr), DestReg).addReg(SrcReg); 86 return true; 87 } 88 } else if (DestRC == ARM::tGPRRegisterClass) { 89 if (SrcRC == ARM::GPRRegisterClass) { 90 BuildMI(MBB, I, DL, get(ARM::tMOVgpr2tgpr), DestReg).addReg(SrcReg); 91 return true; 92 } else if (SrcRC == ARM::tGPRRegisterClass) { 93 BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg).addReg(SrcReg); 94 return true; 95 } 96 } 97 98 return false; 99} 100 101bool Thumb1InstrInfo:: 102canFoldMemoryOperand(const MachineInstr *MI, 103 const SmallVectorImpl<unsigned> &Ops) const { 104 if (Ops.size() != 1) return false; 105 106 unsigned OpNum = Ops[0]; 107 unsigned Opc = MI->getOpcode(); 108 switch (Opc) { 109 default: break; 110 case ARM::tMOVr: 111 case ARM::tMOVtgpr2gpr: 112 case ARM::tMOVgpr2tgpr: 113 case ARM::tMOVgpr2gpr: { 114 if (OpNum == 0) { // move -> store 115 unsigned SrcReg = MI->getOperand(1).getReg(); 116 if (RI.isPhysicalRegister(SrcReg) && !isARMLowRegister(SrcReg)) 117 // tSpill cannot take a high register operand. 118 return false; 119 } else { // move -> load 120 unsigned DstReg = MI->getOperand(0).getReg(); 121 if (RI.isPhysicalRegister(DstReg) && !isARMLowRegister(DstReg)) 122 // tRestore cannot target a high register operand. 123 return false; 124 } 125 return true; 126 } 127 } 128 129 return false; 130} 131 132void Thumb1InstrInfo:: 133storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 134 unsigned SrcReg, bool isKill, int FI, 135 const TargetRegisterClass *RC) const { 136 DebugLoc DL = DebugLoc::getUnknownLoc(); 137 if (I != MBB.end()) DL = I->getDebugLoc(); 138 139 assert(RC == ARM::tGPRRegisterClass && "Unknown regclass!"); 140 141 if (RC == ARM::tGPRRegisterClass) { 142 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::tSpill)) 143 .addReg(SrcReg, getKillRegState(isKill)) 144 .addFrameIndex(FI).addImm(0)); 145 } 146} 147 148void Thumb1InstrInfo:: 149loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 150 unsigned DestReg, int FI, 151 const TargetRegisterClass *RC) const { 152 DebugLoc DL = DebugLoc::getUnknownLoc(); 153 if (I != MBB.end()) DL = I->getDebugLoc(); 154 155 assert(RC == ARM::tGPRRegisterClass && "Unknown regclass!"); 156 157 if (RC == ARM::tGPRRegisterClass) { 158 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::tRestore), DestReg) 159 .addFrameIndex(FI).addImm(0)); 160 } 161} 162 163bool Thumb1InstrInfo:: 164spillCalleeSavedRegisters(MachineBasicBlock &MBB, 165 MachineBasicBlock::iterator MI, 166 const std::vector<CalleeSavedInfo> &CSI) const { 167 if (CSI.empty()) 168 return false; 169 170 DebugLoc DL = DebugLoc::getUnknownLoc(); 171 if (MI != MBB.end()) DL = MI->getDebugLoc(); 172 173 MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, get(ARM::tPUSH)); 174 for (unsigned i = CSI.size(); i != 0; --i) { 175 unsigned Reg = CSI[i-1].getReg(); 176 // Add the callee-saved register as live-in. It's killed at the spill. 177 MBB.addLiveIn(Reg); 178 MIB.addReg(Reg, RegState::Kill); 179 } 180 return true; 181} 182 183bool Thumb1InstrInfo:: 184restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 185 MachineBasicBlock::iterator MI, 186 const std::vector<CalleeSavedInfo> &CSI) const { 187 MachineFunction &MF = *MBB.getParent(); 188 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 189 if (CSI.empty()) 190 return false; 191 192 bool isVarArg = AFI->getVarArgsRegSaveSize() > 0; 193 MachineInstr *PopMI = MF.CreateMachineInstr(get(ARM::tPOP),MI->getDebugLoc()); 194 for (unsigned i = CSI.size(); i != 0; --i) { 195 unsigned Reg = CSI[i-1].getReg(); 196 if (Reg == ARM::LR) { 197 // Special epilogue for vararg functions. See emitEpilogue 198 if (isVarArg) 199 continue; 200 Reg = ARM::PC; 201 PopMI->setDesc(get(ARM::tPOP_RET)); 202 MI = MBB.erase(MI); 203 } 204 PopMI->addOperand(MachineOperand::CreateReg(Reg, true)); 205 } 206 207 // It's illegal to emit pop instruction without operands. 208 if (PopMI->getNumOperands() > 0) 209 MBB.insert(MI, PopMI); 210 211 return true; 212} 213 214MachineInstr *Thumb1InstrInfo:: 215foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, 216 const SmallVectorImpl<unsigned> &Ops, int FI) const { 217 if (Ops.size() != 1) return NULL; 218 219 unsigned OpNum = Ops[0]; 220 unsigned Opc = MI->getOpcode(); 221 MachineInstr *NewMI = NULL; 222 switch (Opc) { 223 default: break; 224 case ARM::tMOVr: 225 case ARM::tMOVtgpr2gpr: 226 case ARM::tMOVgpr2tgpr: 227 case ARM::tMOVgpr2gpr: { 228 if (OpNum == 0) { // move -> store 229 unsigned SrcReg = MI->getOperand(1).getReg(); 230 bool isKill = MI->getOperand(1).isKill(); 231 if (RI.isPhysicalRegister(SrcReg) && !isARMLowRegister(SrcReg)) 232 // tSpill cannot take a high register operand. 233 break; 234 NewMI = AddDefaultPred(BuildMI(MF, MI->getDebugLoc(), get(ARM::tSpill)) 235 .addReg(SrcReg, getKillRegState(isKill)) 236 .addFrameIndex(FI).addImm(0)); 237 } else { // move -> load 238 unsigned DstReg = MI->getOperand(0).getReg(); 239 if (RI.isPhysicalRegister(DstReg) && !isARMLowRegister(DstReg)) 240 // tRestore cannot target a high register operand. 241 break; 242 bool isDead = MI->getOperand(0).isDead(); 243 NewMI = AddDefaultPred(BuildMI(MF, MI->getDebugLoc(), get(ARM::tRestore)) 244 .addReg(DstReg, 245 RegState::Define | getDeadRegState(isDead)) 246 .addFrameIndex(FI).addImm(0)); 247 } 248 break; 249 } 250 } 251 252 return NewMI; 253} 254