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