1235633Sdim//===-- MSP430InstrInfo.cpp - MSP430 Instruction Information --------------===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file contains the MSP430 implementation of the TargetInstrInfo class. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14235633Sdim#include "MSP430InstrInfo.h" 15193323Sed#include "MSP430.h" 16193323Sed#include "MSP430MachineFunctionInfo.h" 17193323Sed#include "MSP430TargetMachine.h" 18193323Sed#include "llvm/CodeGen/MachineFrameInfo.h" 19193323Sed#include "llvm/CodeGen/MachineInstrBuilder.h" 20193323Sed#include "llvm/CodeGen/MachineRegisterInfo.h" 21252723Sdim#include "llvm/IR/Function.h" 22198090Srdivacky#include "llvm/Support/ErrorHandling.h" 23226890Sdim#include "llvm/Support/TargetRegistry.h" 24193323Sed 25263509Sdim#define GET_INSTRINFO_CTOR_DTOR 26224145Sdim#include "MSP430GenInstrInfo.inc" 27224145Sdim 28193323Sedusing namespace llvm; 29193323Sed 30263509Sdim// Pin the vtable to this file. 31263509Sdimvoid MSP430InstrInfo::anchor() {} 32263509Sdim 33193323SedMSP430InstrInfo::MSP430InstrInfo(MSP430TargetMachine &tm) 34224145Sdim : MSP430GenInstrInfo(MSP430::ADJCALLSTACKDOWN, MSP430::ADJCALLSTACKUP), 35263509Sdim RI(tm) {} 36193323Sed 37193323Sedvoid MSP430InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 38193323Sed MachineBasicBlock::iterator MI, 39193323Sed unsigned SrcReg, bool isKill, int FrameIdx, 40208599Srdivacky const TargetRegisterClass *RC, 41208599Srdivacky const TargetRegisterInfo *TRI) const { 42206124Srdivacky DebugLoc DL; 43193323Sed if (MI != MBB.end()) DL = MI->getDebugLoc(); 44199481Srdivacky MachineFunction &MF = *MBB.getParent(); 45199481Srdivacky MachineFrameInfo &MFI = *MF.getFrameInfo(); 46193323Sed 47199481Srdivacky MachineMemOperand *MMO = 48235633Sdim MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIdx), 49218893Sdim MachineMemOperand::MOStore, 50199481Srdivacky MFI.getObjectSize(FrameIdx), 51199481Srdivacky MFI.getObjectAlignment(FrameIdx)); 52199481Srdivacky 53193323Sed if (RC == &MSP430::GR16RegClass) 54193323Sed BuildMI(MBB, MI, DL, get(MSP430::MOV16mr)) 55193323Sed .addFrameIndex(FrameIdx).addImm(0) 56199481Srdivacky .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO); 57193323Sed else if (RC == &MSP430::GR8RegClass) 58193323Sed BuildMI(MBB, MI, DL, get(MSP430::MOV8mr)) 59193323Sed .addFrameIndex(FrameIdx).addImm(0) 60199481Srdivacky .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO); 61193323Sed else 62198090Srdivacky llvm_unreachable("Cannot store this register to stack slot!"); 63193323Sed} 64193323Sed 65193323Sedvoid MSP430InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 66193323Sed MachineBasicBlock::iterator MI, 67193323Sed unsigned DestReg, int FrameIdx, 68208599Srdivacky const TargetRegisterClass *RC, 69208599Srdivacky const TargetRegisterInfo *TRI) const{ 70206124Srdivacky DebugLoc DL; 71193323Sed if (MI != MBB.end()) DL = MI->getDebugLoc(); 72199481Srdivacky MachineFunction &MF = *MBB.getParent(); 73199481Srdivacky MachineFrameInfo &MFI = *MF.getFrameInfo(); 74193323Sed 75199481Srdivacky MachineMemOperand *MMO = 76235633Sdim MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIdx), 77218893Sdim MachineMemOperand::MOLoad, 78199481Srdivacky MFI.getObjectSize(FrameIdx), 79199481Srdivacky MFI.getObjectAlignment(FrameIdx)); 80199481Srdivacky 81193323Sed if (RC == &MSP430::GR16RegClass) 82193323Sed BuildMI(MBB, MI, DL, get(MSP430::MOV16rm)) 83199481Srdivacky .addReg(DestReg).addFrameIndex(FrameIdx).addImm(0).addMemOperand(MMO); 84193323Sed else if (RC == &MSP430::GR8RegClass) 85193323Sed BuildMI(MBB, MI, DL, get(MSP430::MOV8rm)) 86199481Srdivacky .addReg(DestReg).addFrameIndex(FrameIdx).addImm(0).addMemOperand(MMO); 87193323Sed else 88198090Srdivacky llvm_unreachable("Cannot store this register to stack slot!"); 89193323Sed} 90193323Sed 91210299Sedvoid MSP430InstrInfo::copyPhysReg(MachineBasicBlock &MBB, 92210299Sed MachineBasicBlock::iterator I, DebugLoc DL, 93210299Sed unsigned DestReg, unsigned SrcReg, 94210299Sed bool KillSrc) const { 95210299Sed unsigned Opc; 96210299Sed if (MSP430::GR16RegClass.contains(DestReg, SrcReg)) 97210299Sed Opc = MSP430::MOV16rr; 98210299Sed else if (MSP430::GR8RegClass.contains(DestReg, SrcReg)) 99210299Sed Opc = MSP430::MOV8rr; 100210299Sed else 101210299Sed llvm_unreachable("Impossible reg-to-reg copy"); 102193323Sed 103210299Sed BuildMI(MBB, I, DL, get(Opc), DestReg) 104210299Sed .addReg(SrcReg, getKillRegState(KillSrc)); 105193323Sed} 106193323Sed 107198396Srdivackyunsigned MSP430InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 108198396Srdivacky MachineBasicBlock::iterator I = MBB.end(); 109198396Srdivacky unsigned Count = 0; 110198396Srdivacky 111198396Srdivacky while (I != MBB.begin()) { 112198396Srdivacky --I; 113206083Srdivacky if (I->isDebugValue()) 114206083Srdivacky continue; 115198396Srdivacky if (I->getOpcode() != MSP430::JMP && 116207618Srdivacky I->getOpcode() != MSP430::JCC && 117207618Srdivacky I->getOpcode() != MSP430::Br && 118207618Srdivacky I->getOpcode() != MSP430::Bm) 119198396Srdivacky break; 120198396Srdivacky // Remove the branch. 121198396Srdivacky I->eraseFromParent(); 122198396Srdivacky I = MBB.end(); 123198396Srdivacky ++Count; 124198396Srdivacky } 125198396Srdivacky 126198396Srdivacky return Count; 127198396Srdivacky} 128198396Srdivacky 129198396Srdivackybool MSP430InstrInfo:: 130198396SrdivackyReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 131198396Srdivacky assert(Cond.size() == 1 && "Invalid Xbranch condition!"); 132198396Srdivacky 133198396Srdivacky MSP430CC::CondCodes CC = static_cast<MSP430CC::CondCodes>(Cond[0].getImm()); 134198396Srdivacky 135198396Srdivacky switch (CC) { 136235633Sdim default: llvm_unreachable("Invalid branch condition!"); 137198396Srdivacky case MSP430CC::COND_E: 138198396Srdivacky CC = MSP430CC::COND_NE; 139198396Srdivacky break; 140198396Srdivacky case MSP430CC::COND_NE: 141198396Srdivacky CC = MSP430CC::COND_E; 142198396Srdivacky break; 143198396Srdivacky case MSP430CC::COND_L: 144198396Srdivacky CC = MSP430CC::COND_GE; 145198396Srdivacky break; 146198396Srdivacky case MSP430CC::COND_GE: 147198396Srdivacky CC = MSP430CC::COND_L; 148198396Srdivacky break; 149198396Srdivacky case MSP430CC::COND_HS: 150198396Srdivacky CC = MSP430CC::COND_LO; 151198396Srdivacky break; 152198396Srdivacky case MSP430CC::COND_LO: 153198396Srdivacky CC = MSP430CC::COND_HS; 154198396Srdivacky break; 155198396Srdivacky } 156198396Srdivacky 157198396Srdivacky Cond[0].setImm(CC); 158198396Srdivacky return false; 159198396Srdivacky} 160198396Srdivacky 161198396Srdivackybool MSP430InstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const { 162235633Sdim if (!MI->isTerminator()) return false; 163198396Srdivacky 164198396Srdivacky // Conditional branch is a special case. 165235633Sdim if (MI->isBranch() && !MI->isBarrier()) 166198396Srdivacky return true; 167235633Sdim if (!MI->isPredicable()) 168198396Srdivacky return true; 169198396Srdivacky return !isPredicated(MI); 170198396Srdivacky} 171198396Srdivacky 172198396Srdivackybool MSP430InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, 173198396Srdivacky MachineBasicBlock *&TBB, 174198396Srdivacky MachineBasicBlock *&FBB, 175198396Srdivacky SmallVectorImpl<MachineOperand> &Cond, 176198396Srdivacky bool AllowModify) const { 177198396Srdivacky // Start from the bottom of the block and work up, examining the 178198396Srdivacky // terminator instructions. 179198396Srdivacky MachineBasicBlock::iterator I = MBB.end(); 180198396Srdivacky while (I != MBB.begin()) { 181198396Srdivacky --I; 182206083Srdivacky if (I->isDebugValue()) 183206083Srdivacky continue; 184206083Srdivacky 185198396Srdivacky // Working from the bottom, when we see a non-terminator 186198396Srdivacky // instruction, we're done. 187198396Srdivacky if (!isUnpredicatedTerminator(I)) 188198396Srdivacky break; 189198396Srdivacky 190198396Srdivacky // A terminator that isn't a branch can't easily be handled 191198396Srdivacky // by this analysis. 192235633Sdim if (!I->isBranch()) 193198396Srdivacky return true; 194198396Srdivacky 195207618Srdivacky // Cannot handle indirect branches. 196207618Srdivacky if (I->getOpcode() == MSP430::Br || 197207618Srdivacky I->getOpcode() == MSP430::Bm) 198207618Srdivacky return true; 199207618Srdivacky 200198396Srdivacky // Handle unconditional branches. 201198396Srdivacky if (I->getOpcode() == MSP430::JMP) { 202198396Srdivacky if (!AllowModify) { 203198396Srdivacky TBB = I->getOperand(0).getMBB(); 204198396Srdivacky continue; 205198396Srdivacky } 206198396Srdivacky 207198396Srdivacky // If the block has any instructions after a JMP, delete them. 208200581Srdivacky while (llvm::next(I) != MBB.end()) 209200581Srdivacky llvm::next(I)->eraseFromParent(); 210198396Srdivacky Cond.clear(); 211198396Srdivacky FBB = 0; 212198396Srdivacky 213198396Srdivacky // Delete the JMP if it's equivalent to a fall-through. 214198396Srdivacky if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) { 215198396Srdivacky TBB = 0; 216198396Srdivacky I->eraseFromParent(); 217198396Srdivacky I = MBB.end(); 218198396Srdivacky continue; 219198396Srdivacky } 220198396Srdivacky 221198396Srdivacky // TBB is used to indicate the unconditinal destination. 222198396Srdivacky TBB = I->getOperand(0).getMBB(); 223198396Srdivacky continue; 224198396Srdivacky } 225198396Srdivacky 226198396Srdivacky // Handle conditional branches. 227198396Srdivacky assert(I->getOpcode() == MSP430::JCC && "Invalid conditional branch"); 228198396Srdivacky MSP430CC::CondCodes BranchCode = 229198396Srdivacky static_cast<MSP430CC::CondCodes>(I->getOperand(1).getImm()); 230198396Srdivacky if (BranchCode == MSP430CC::COND_INVALID) 231198396Srdivacky return true; // Can't handle weird stuff. 232198396Srdivacky 233198396Srdivacky // Working from the bottom, handle the first conditional branch. 234198396Srdivacky if (Cond.empty()) { 235198396Srdivacky FBB = TBB; 236198396Srdivacky TBB = I->getOperand(0).getMBB(); 237198396Srdivacky Cond.push_back(MachineOperand::CreateImm(BranchCode)); 238198396Srdivacky continue; 239198396Srdivacky } 240198396Srdivacky 241198396Srdivacky // Handle subsequent conditional branches. Only handle the case where all 242198396Srdivacky // conditional branches branch to the same destination. 243198396Srdivacky assert(Cond.size() == 1); 244198396Srdivacky assert(TBB); 245198396Srdivacky 246198396Srdivacky // Only handle the case where all conditional branches branch to 247198396Srdivacky // the same destination. 248198396Srdivacky if (TBB != I->getOperand(0).getMBB()) 249198396Srdivacky return true; 250198396Srdivacky 251198396Srdivacky MSP430CC::CondCodes OldBranchCode = (MSP430CC::CondCodes)Cond[0].getImm(); 252198396Srdivacky // If the conditions are the same, we can leave them alone. 253198396Srdivacky if (OldBranchCode == BranchCode) 254198396Srdivacky continue; 255198396Srdivacky 256198396Srdivacky return true; 257198396Srdivacky } 258198396Srdivacky 259198396Srdivacky return false; 260198396Srdivacky} 261198396Srdivacky 262193323Sedunsigned 263193323SedMSP430InstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 264193323Sed MachineBasicBlock *FBB, 265210299Sed const SmallVectorImpl<MachineOperand> &Cond, 266210299Sed DebugLoc DL) const { 267193323Sed // Shouldn't be a fall through. 268193323Sed assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 269193323Sed assert((Cond.size() == 1 || Cond.size() == 0) && 270193323Sed "MSP430 branch conditions have one component!"); 271193323Sed 272193323Sed if (Cond.empty()) { 273193323Sed // Unconditional branch? 274193323Sed assert(!FBB && "Unconditional branch with multiple successors!"); 275206124Srdivacky BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(TBB); 276193323Sed return 1; 277193323Sed } 278193323Sed 279193323Sed // Conditional branch. 280193323Sed unsigned Count = 0; 281206124Srdivacky BuildMI(&MBB, DL, get(MSP430::JCC)).addMBB(TBB).addImm(Cond[0].getImm()); 282198396Srdivacky ++Count; 283193323Sed 284198396Srdivacky if (FBB) { 285198396Srdivacky // Two-way Conditional branch. Insert the second branch. 286206124Srdivacky BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(FBB); 287198396Srdivacky ++Count; 288198396Srdivacky } 289193323Sed return Count; 290193323Sed} 291202878Srdivacky 292202878Srdivacky/// GetInstSize - Return the number of bytes of code the specified 293202878Srdivacky/// instruction may be. This returns the maximum number of bytes. 294202878Srdivacky/// 295202878Srdivackyunsigned MSP430InstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const { 296224145Sdim const MCInstrDesc &Desc = MI->getDesc(); 297202878Srdivacky 298202878Srdivacky switch (Desc.TSFlags & MSP430II::SizeMask) { 299202878Srdivacky default: 300202878Srdivacky switch (Desc.getOpcode()) { 301235633Sdim default: llvm_unreachable("Unknown instruction size!"); 302212904Sdim case TargetOpcode::PROLOG_LABEL: 303203954Srdivacky case TargetOpcode::EH_LABEL: 304203954Srdivacky case TargetOpcode::IMPLICIT_DEF: 305203954Srdivacky case TargetOpcode::KILL: 306207618Srdivacky case TargetOpcode::DBG_VALUE: 307202878Srdivacky return 0; 308203954Srdivacky case TargetOpcode::INLINEASM: { 309202878Srdivacky const MachineFunction *MF = MI->getParent()->getParent(); 310202878Srdivacky const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo(); 311202878Srdivacky return TII.getInlineAsmLength(MI->getOperand(0).getSymbolName(), 312202878Srdivacky *MF->getTarget().getMCAsmInfo()); 313202878Srdivacky } 314202878Srdivacky } 315202878Srdivacky case MSP430II::SizeSpecial: 316202878Srdivacky switch (MI->getOpcode()) { 317235633Sdim default: llvm_unreachable("Unknown instruction size!"); 318202878Srdivacky case MSP430::SAR8r1c: 319202878Srdivacky case MSP430::SAR16r1c: 320202878Srdivacky return 4; 321202878Srdivacky } 322202878Srdivacky case MSP430II::Size2Bytes: 323202878Srdivacky return 2; 324202878Srdivacky case MSP430II::Size4Bytes: 325202878Srdivacky return 4; 326202878Srdivacky case MSP430II::Size6Bytes: 327202878Srdivacky return 6; 328202878Srdivacky } 329202878Srdivacky} 330