MSP430InstrInfo.cpp revision 83fceb948165adb50c450ff28d51d0a99615b854
1//===- MSP430InstrInfo.cpp - MSP430 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 MSP430 implementation of the TargetInstrInfo class. 11// 12//===----------------------------------------------------------------------===// 13 14#include "MSP430.h" 15#include "MSP430InstrInfo.h" 16#include "MSP430MachineFunctionInfo.h" 17#include "MSP430TargetMachine.h" 18#include "MSP430GenInstrInfo.inc" 19#include "llvm/Function.h" 20#include "llvm/CodeGen/MachineFrameInfo.h" 21#include "llvm/CodeGen/MachineInstrBuilder.h" 22#include "llvm/CodeGen/MachineRegisterInfo.h" 23#include "llvm/CodeGen/PseudoSourceValue.h" 24#include "llvm/Support/ErrorHandling.h" 25 26using namespace llvm; 27 28MSP430InstrInfo::MSP430InstrInfo(MSP430TargetMachine &tm) 29 : TargetInstrInfoImpl(MSP430Insts, array_lengthof(MSP430Insts)), 30 RI(tm, *this), TM(tm) {} 31 32void MSP430InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 33 MachineBasicBlock::iterator MI, 34 unsigned SrcReg, bool isKill, int FrameIdx, 35 const TargetRegisterClass *RC) const { 36 DebugLoc DL = DebugLoc::getUnknownLoc(); 37 if (MI != MBB.end()) DL = MI->getDebugLoc(); 38 39 if (RC == &MSP430::GR16RegClass) 40 BuildMI(MBB, MI, DL, get(MSP430::MOV16mr)) 41 .addFrameIndex(FrameIdx).addImm(0) 42 .addReg(SrcReg, getKillRegState(isKill)); 43 else if (RC == &MSP430::GR8RegClass) 44 BuildMI(MBB, MI, DL, get(MSP430::MOV8mr)) 45 .addFrameIndex(FrameIdx).addImm(0) 46 .addReg(SrcReg, getKillRegState(isKill)); 47 else 48 llvm_unreachable("Cannot store this register to stack slot!"); 49} 50 51void MSP430InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 52 MachineBasicBlock::iterator MI, 53 unsigned DestReg, int FrameIdx, 54 const TargetRegisterClass *RC) const{ 55 DebugLoc DL = DebugLoc::getUnknownLoc(); 56 if (MI != MBB.end()) DL = MI->getDebugLoc(); 57 58 if (RC == &MSP430::GR16RegClass) 59 BuildMI(MBB, MI, DL, get(MSP430::MOV16rm)) 60 .addReg(DestReg).addFrameIndex(FrameIdx).addImm(0); 61 else if (RC == &MSP430::GR8RegClass) 62 BuildMI(MBB, MI, DL, get(MSP430::MOV8rm)) 63 .addReg(DestReg).addFrameIndex(FrameIdx).addImm(0); 64 else 65 llvm_unreachable("Cannot store this register to stack slot!"); 66} 67 68bool MSP430InstrInfo::copyRegToReg(MachineBasicBlock &MBB, 69 MachineBasicBlock::iterator I, 70 unsigned DestReg, unsigned SrcReg, 71 const TargetRegisterClass *DestRC, 72 const TargetRegisterClass *SrcRC) const { 73 DebugLoc DL = DebugLoc::getUnknownLoc(); 74 if (I != MBB.end()) DL = I->getDebugLoc(); 75 76 if (DestRC == SrcRC) { 77 unsigned Opc; 78 if (DestRC == &MSP430::GR16RegClass) { 79 Opc = MSP430::MOV16rr; 80 } else if (DestRC == &MSP430::GR8RegClass) { 81 Opc = MSP430::MOV8rr; 82 } else { 83 return false; 84 } 85 86 BuildMI(MBB, I, DL, get(Opc), DestReg).addReg(SrcReg); 87 return true; 88 } 89 90 return false; 91} 92 93bool 94MSP430InstrInfo::isMoveInstr(const MachineInstr& MI, 95 unsigned &SrcReg, unsigned &DstReg, 96 unsigned &SrcSubIdx, unsigned &DstSubIdx) const { 97 SrcSubIdx = DstSubIdx = 0; // No sub-registers yet. 98 99 switch (MI.getOpcode()) { 100 default: 101 return false; 102 case MSP430::MOV8rr: 103 case MSP430::MOV16rr: 104 assert(MI.getNumOperands() >= 2 && 105 MI.getOperand(0).isReg() && 106 MI.getOperand(1).isReg() && 107 "invalid register-register move instruction"); 108 SrcReg = MI.getOperand(1).getReg(); 109 DstReg = MI.getOperand(0).getReg(); 110 return true; 111 } 112} 113 114bool 115MSP430InstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB, 116 MachineBasicBlock::iterator MI, 117 const std::vector<CalleeSavedInfo> &CSI) const { 118 if (CSI.empty()) 119 return false; 120 121 DebugLoc DL = DebugLoc::getUnknownLoc(); 122 if (MI != MBB.end()) DL = MI->getDebugLoc(); 123 124 MachineFunction &MF = *MBB.getParent(); 125 MSP430MachineFunctionInfo *MFI = MF.getInfo<MSP430MachineFunctionInfo>(); 126 MFI->setCalleeSavedFrameSize(CSI.size() * 2); 127 128 for (unsigned i = CSI.size(); i != 0; --i) { 129 unsigned Reg = CSI[i-1].getReg(); 130 // Add the callee-saved register as live-in. It's killed at the spill. 131 MBB.addLiveIn(Reg); 132 BuildMI(MBB, MI, DL, get(MSP430::PUSH16r)) 133 .addReg(Reg, RegState::Kill); 134 } 135 return true; 136} 137 138bool 139MSP430InstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 140 MachineBasicBlock::iterator MI, 141 const std::vector<CalleeSavedInfo> &CSI) const { 142 if (CSI.empty()) 143 return false; 144 145 DebugLoc DL = DebugLoc::getUnknownLoc(); 146 if (MI != MBB.end()) DL = MI->getDebugLoc(); 147 148 for (unsigned i = 0, e = CSI.size(); i != e; ++i) 149 BuildMI(MBB, MI, DL, get(MSP430::POP16r), CSI[i].getReg()); 150 151 return true; 152} 153 154unsigned MSP430InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 155 MachineBasicBlock::iterator I = MBB.end(); 156 unsigned Count = 0; 157 158 while (I != MBB.begin()) { 159 --I; 160 if (I->getOpcode() != MSP430::JMP && 161 I->getOpcode() != MSP430::JCC) 162 break; 163 // Remove the branch. 164 I->eraseFromParent(); 165 I = MBB.end(); 166 ++Count; 167 } 168 169 return Count; 170} 171 172bool MSP430InstrInfo:: 173ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 174 assert(Cond.size() == 1 && "Invalid Xbranch condition!"); 175 176 MSP430CC::CondCodes CC = static_cast<MSP430CC::CondCodes>(Cond[0].getImm()); 177 178 switch (CC) { 179 default: 180 assert(0 && "Invalid branch condition!"); 181 break; 182 case MSP430CC::COND_E: 183 CC = MSP430CC::COND_NE; 184 break; 185 case MSP430CC::COND_NE: 186 CC = MSP430CC::COND_E; 187 break; 188 case MSP430CC::COND_L: 189 CC = MSP430CC::COND_GE; 190 break; 191 case MSP430CC::COND_GE: 192 CC = MSP430CC::COND_L; 193 break; 194 case MSP430CC::COND_HS: 195 CC = MSP430CC::COND_LO; 196 break; 197 case MSP430CC::COND_LO: 198 CC = MSP430CC::COND_HS; 199 break; 200 } 201 202 Cond[0].setImm(CC); 203 return false; 204} 205 206bool MSP430InstrInfo::BlockHasNoFallThrough(const MachineBasicBlock &MBB)const{ 207 if (MBB.empty()) return false; 208 209 switch (MBB.back().getOpcode()) { 210 case MSP430::RET: // Return. 211 case MSP430::JMP: // Uncond branch. 212 return true; 213 default: return false; 214 } 215} 216 217bool MSP430InstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const { 218 const TargetInstrDesc &TID = MI->getDesc(); 219 if (!TID.isTerminator()) return false; 220 221 // Conditional branch is a special case. 222 if (TID.isBranch() && !TID.isBarrier()) 223 return true; 224 if (!TID.isPredicable()) 225 return true; 226 return !isPredicated(MI); 227} 228 229bool MSP430InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, 230 MachineBasicBlock *&TBB, 231 MachineBasicBlock *&FBB, 232 SmallVectorImpl<MachineOperand> &Cond, 233 bool AllowModify) const { 234 // Start from the bottom of the block and work up, examining the 235 // terminator instructions. 236 MachineBasicBlock::iterator I = MBB.end(); 237 while (I != MBB.begin()) { 238 --I; 239 // Working from the bottom, when we see a non-terminator 240 // instruction, we're done. 241 if (!isUnpredicatedTerminator(I)) 242 break; 243 244 // A terminator that isn't a branch can't easily be handled 245 // by this analysis. 246 if (!I->getDesc().isBranch()) 247 return true; 248 249 // Handle unconditional branches. 250 if (I->getOpcode() == MSP430::JMP) { 251 if (!AllowModify) { 252 TBB = I->getOperand(0).getMBB(); 253 continue; 254 } 255 256 // If the block has any instructions after a JMP, delete them. 257 while (next(I) != MBB.end()) 258 next(I)->eraseFromParent(); 259 Cond.clear(); 260 FBB = 0; 261 262 // Delete the JMP if it's equivalent to a fall-through. 263 if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) { 264 TBB = 0; 265 I->eraseFromParent(); 266 I = MBB.end(); 267 continue; 268 } 269 270 // TBB is used to indicate the unconditinal destination. 271 TBB = I->getOperand(0).getMBB(); 272 continue; 273 } 274 275 // Handle conditional branches. 276 assert(I->getOpcode() == MSP430::JCC && "Invalid conditional branch"); 277 MSP430CC::CondCodes BranchCode = 278 static_cast<MSP430CC::CondCodes>(I->getOperand(1).getImm()); 279 if (BranchCode == MSP430CC::COND_INVALID) 280 return true; // Can't handle weird stuff. 281 282 // Working from the bottom, handle the first conditional branch. 283 if (Cond.empty()) { 284 FBB = TBB; 285 TBB = I->getOperand(0).getMBB(); 286 Cond.push_back(MachineOperand::CreateImm(BranchCode)); 287 continue; 288 } 289 290 // Handle subsequent conditional branches. Only handle the case where all 291 // conditional branches branch to the same destination. 292 assert(Cond.size() == 1); 293 assert(TBB); 294 295 // Only handle the case where all conditional branches branch to 296 // the same destination. 297 if (TBB != I->getOperand(0).getMBB()) 298 return true; 299 300 MSP430CC::CondCodes OldBranchCode = (MSP430CC::CondCodes)Cond[0].getImm(); 301 // If the conditions are the same, we can leave them alone. 302 if (OldBranchCode == BranchCode) 303 continue; 304 305 return true; 306 } 307 308 return false; 309} 310 311unsigned 312MSP430InstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 313 MachineBasicBlock *FBB, 314 const SmallVectorImpl<MachineOperand> &Cond) const { 315 // FIXME this should probably have a DebugLoc operand 316 DebugLoc dl = DebugLoc::getUnknownLoc(); 317 318 // Shouldn't be a fall through. 319 assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 320 assert((Cond.size() == 1 || Cond.size() == 0) && 321 "MSP430 branch conditions have one component!"); 322 323 if (Cond.empty()) { 324 // Unconditional branch? 325 assert(!FBB && "Unconditional branch with multiple successors!"); 326 BuildMI(&MBB, dl, get(MSP430::JMP)).addMBB(TBB); 327 return 1; 328 } 329 330 // Conditional branch. 331 unsigned Count = 0; 332 BuildMI(&MBB, dl, get(MSP430::JCC)).addMBB(TBB).addImm(Cond[0].getImm()); 333 ++Count; 334 335 if (FBB) { 336 // Two-way Conditional branch. Insert the second branch. 337 BuildMI(&MBB, dl, get(MSP430::JMP)).addMBB(FBB); 338 ++Count; 339 } 340 return Count; 341} 342