1234353Sdim//===-- MSP430InstrInfo.cpp - MSP430 Instruction Information --------------===// 2193323Sed// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6193323Sed// 7193323Sed//===----------------------------------------------------------------------===// 8193323Sed// 9193323Sed// This file contains the MSP430 implementation of the TargetInstrInfo class. 10193323Sed// 11193323Sed//===----------------------------------------------------------------------===// 12193323Sed 13234353Sdim#include "MSP430InstrInfo.h" 14193323Sed#include "MSP430.h" 15193323Sed#include "MSP430MachineFunctionInfo.h" 16193323Sed#include "MSP430TargetMachine.h" 17193323Sed#include "llvm/CodeGen/MachineFrameInfo.h" 18193323Sed#include "llvm/CodeGen/MachineInstrBuilder.h" 19193323Sed#include "llvm/CodeGen/MachineRegisterInfo.h" 20249423Sdim#include "llvm/IR/Function.h" 21198090Srdivacky#include "llvm/Support/ErrorHandling.h" 22226633Sdim#include "llvm/Support/TargetRegistry.h" 23193323Sed 24276479Sdimusing namespace llvm; 25276479Sdim 26261991Sdim#define GET_INSTRINFO_CTOR_DTOR 27224145Sdim#include "MSP430GenInstrInfo.inc" 28224145Sdim 29261991Sdim// Pin the vtable to this file. 30261991Sdimvoid MSP430InstrInfo::anchor() {} 31261991Sdim 32276479SdimMSP430InstrInfo::MSP430InstrInfo(MSP430Subtarget &STI) 33224145Sdim : MSP430GenInstrInfo(MSP430::ADJCALLSTACKDOWN, MSP430::ADJCALLSTACKUP), 34276479Sdim RI() {} 35193323Sed 36193323Sedvoid MSP430InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 37193323Sed MachineBasicBlock::iterator MI, 38193323Sed unsigned SrcReg, bool isKill, int FrameIdx, 39208599Srdivacky const TargetRegisterClass *RC, 40208599Srdivacky const TargetRegisterInfo *TRI) const { 41206124Srdivacky DebugLoc DL; 42193323Sed if (MI != MBB.end()) DL = MI->getDebugLoc(); 43199481Srdivacky MachineFunction &MF = *MBB.getParent(); 44314564Sdim MachineFrameInfo &MFI = MF.getFrameInfo(); 45193323Sed 46296417Sdim MachineMemOperand *MMO = MF.getMachineMemOperand( 47296417Sdim MachinePointerInfo::getFixedStack(MF, FrameIdx), 48296417Sdim MachineMemOperand::MOStore, MFI.getObjectSize(FrameIdx), 49296417Sdim MFI.getObjectAlignment(FrameIdx)); 50199481Srdivacky 51193323Sed if (RC == &MSP430::GR16RegClass) 52193323Sed BuildMI(MBB, MI, DL, get(MSP430::MOV16mr)) 53193323Sed .addFrameIndex(FrameIdx).addImm(0) 54199481Srdivacky .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO); 55193323Sed else if (RC == &MSP430::GR8RegClass) 56193323Sed BuildMI(MBB, MI, DL, get(MSP430::MOV8mr)) 57193323Sed .addFrameIndex(FrameIdx).addImm(0) 58199481Srdivacky .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO); 59193323Sed else 60198090Srdivacky llvm_unreachable("Cannot store this register to stack slot!"); 61193323Sed} 62193323Sed 63193323Sedvoid MSP430InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 64193323Sed MachineBasicBlock::iterator MI, 65193323Sed unsigned DestReg, int FrameIdx, 66208599Srdivacky const TargetRegisterClass *RC, 67208599Srdivacky const TargetRegisterInfo *TRI) const{ 68206124Srdivacky DebugLoc DL; 69193323Sed if (MI != MBB.end()) DL = MI->getDebugLoc(); 70199481Srdivacky MachineFunction &MF = *MBB.getParent(); 71314564Sdim MachineFrameInfo &MFI = MF.getFrameInfo(); 72193323Sed 73296417Sdim MachineMemOperand *MMO = MF.getMachineMemOperand( 74296417Sdim MachinePointerInfo::getFixedStack(MF, FrameIdx), 75296417Sdim MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIdx), 76296417Sdim MFI.getObjectAlignment(FrameIdx)); 77199481Srdivacky 78193323Sed if (RC == &MSP430::GR16RegClass) 79193323Sed BuildMI(MBB, MI, DL, get(MSP430::MOV16rm)) 80309124Sdim .addReg(DestReg, getDefRegState(true)).addFrameIndex(FrameIdx) 81309124Sdim .addImm(0).addMemOperand(MMO); 82193323Sed else if (RC == &MSP430::GR8RegClass) 83193323Sed BuildMI(MBB, MI, DL, get(MSP430::MOV8rm)) 84309124Sdim .addReg(DestReg, getDefRegState(true)).addFrameIndex(FrameIdx) 85309124Sdim .addImm(0).addMemOperand(MMO); 86193323Sed else 87198090Srdivacky llvm_unreachable("Cannot store this register to stack slot!"); 88193323Sed} 89193323Sed 90210299Sedvoid MSP430InstrInfo::copyPhysReg(MachineBasicBlock &MBB, 91309124Sdim MachineBasicBlock::iterator I, 92360784Sdim const DebugLoc &DL, MCRegister DestReg, 93360784Sdim MCRegister SrcReg, bool KillSrc) const { 94210299Sed unsigned Opc; 95210299Sed if (MSP430::GR16RegClass.contains(DestReg, SrcReg)) 96210299Sed Opc = MSP430::MOV16rr; 97210299Sed else if (MSP430::GR8RegClass.contains(DestReg, SrcReg)) 98210299Sed Opc = MSP430::MOV8rr; 99210299Sed else 100210299Sed llvm_unreachable("Impossible reg-to-reg copy"); 101193323Sed 102210299Sed BuildMI(MBB, I, DL, get(Opc), DestReg) 103210299Sed .addReg(SrcReg, getKillRegState(KillSrc)); 104193323Sed} 105193323Sed 106314564Sdimunsigned MSP430InstrInfo::removeBranch(MachineBasicBlock &MBB, 107314564Sdim int *BytesRemoved) const { 108314564Sdim assert(!BytesRemoved && "code size not handled"); 109314564Sdim 110198396Srdivacky MachineBasicBlock::iterator I = MBB.end(); 111198396Srdivacky unsigned Count = 0; 112198396Srdivacky 113198396Srdivacky while (I != MBB.begin()) { 114198396Srdivacky --I; 115341825Sdim if (I->isDebugInstr()) 116206083Srdivacky continue; 117198396Srdivacky if (I->getOpcode() != MSP430::JMP && 118207618Srdivacky I->getOpcode() != MSP430::JCC && 119207618Srdivacky I->getOpcode() != MSP430::Br && 120207618Srdivacky I->getOpcode() != MSP430::Bm) 121198396Srdivacky break; 122198396Srdivacky // Remove the branch. 123198396Srdivacky I->eraseFromParent(); 124198396Srdivacky I = MBB.end(); 125198396Srdivacky ++Count; 126198396Srdivacky } 127198396Srdivacky 128198396Srdivacky return Count; 129198396Srdivacky} 130198396Srdivacky 131198396Srdivackybool MSP430InstrInfo:: 132314564SdimreverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 133198396Srdivacky assert(Cond.size() == 1 && "Invalid Xbranch condition!"); 134198396Srdivacky 135198396Srdivacky MSP430CC::CondCodes CC = static_cast<MSP430CC::CondCodes>(Cond[0].getImm()); 136198396Srdivacky 137198396Srdivacky switch (CC) { 138234353Sdim default: llvm_unreachable("Invalid branch condition!"); 139198396Srdivacky case MSP430CC::COND_E: 140198396Srdivacky CC = MSP430CC::COND_NE; 141198396Srdivacky break; 142198396Srdivacky case MSP430CC::COND_NE: 143198396Srdivacky CC = MSP430CC::COND_E; 144198396Srdivacky break; 145198396Srdivacky case MSP430CC::COND_L: 146198396Srdivacky CC = MSP430CC::COND_GE; 147198396Srdivacky break; 148198396Srdivacky case MSP430CC::COND_GE: 149198396Srdivacky CC = MSP430CC::COND_L; 150198396Srdivacky break; 151198396Srdivacky case MSP430CC::COND_HS: 152198396Srdivacky CC = MSP430CC::COND_LO; 153198396Srdivacky break; 154198396Srdivacky case MSP430CC::COND_LO: 155198396Srdivacky CC = MSP430CC::COND_HS; 156198396Srdivacky break; 157198396Srdivacky } 158198396Srdivacky 159198396Srdivacky Cond[0].setImm(CC); 160198396Srdivacky return false; 161198396Srdivacky} 162198396Srdivacky 163309124Sdimbool MSP430InstrInfo::isUnpredicatedTerminator(const MachineInstr &MI) const { 164309124Sdim if (!MI.isTerminator()) 165309124Sdim return false; 166198396Srdivacky 167198396Srdivacky // Conditional branch is a special case. 168309124Sdim if (MI.isBranch() && !MI.isBarrier()) 169198396Srdivacky return true; 170309124Sdim if (!MI.isPredicable()) 171198396Srdivacky return true; 172198396Srdivacky return !isPredicated(MI); 173198396Srdivacky} 174198396Srdivacky 175309124Sdimbool MSP430InstrInfo::analyzeBranch(MachineBasicBlock &MBB, 176198396Srdivacky MachineBasicBlock *&TBB, 177198396Srdivacky MachineBasicBlock *&FBB, 178198396Srdivacky SmallVectorImpl<MachineOperand> &Cond, 179198396Srdivacky bool AllowModify) const { 180198396Srdivacky // Start from the bottom of the block and work up, examining the 181198396Srdivacky // terminator instructions. 182198396Srdivacky MachineBasicBlock::iterator I = MBB.end(); 183198396Srdivacky while (I != MBB.begin()) { 184198396Srdivacky --I; 185341825Sdim if (I->isDebugInstr()) 186206083Srdivacky continue; 187206083Srdivacky 188198396Srdivacky // Working from the bottom, when we see a non-terminator 189198396Srdivacky // instruction, we're done. 190309124Sdim if (!isUnpredicatedTerminator(*I)) 191198396Srdivacky break; 192198396Srdivacky 193198396Srdivacky // A terminator that isn't a branch can't easily be handled 194198396Srdivacky // by this analysis. 195234353Sdim if (!I->isBranch()) 196198396Srdivacky return true; 197198396Srdivacky 198207618Srdivacky // Cannot handle indirect branches. 199207618Srdivacky if (I->getOpcode() == MSP430::Br || 200207618Srdivacky I->getOpcode() == MSP430::Bm) 201207618Srdivacky return true; 202207618Srdivacky 203198396Srdivacky // Handle unconditional branches. 204198396Srdivacky if (I->getOpcode() == MSP430::JMP) { 205198396Srdivacky if (!AllowModify) { 206198396Srdivacky TBB = I->getOperand(0).getMBB(); 207198396Srdivacky continue; 208198396Srdivacky } 209198396Srdivacky 210198396Srdivacky // If the block has any instructions after a JMP, delete them. 211276479Sdim while (std::next(I) != MBB.end()) 212276479Sdim std::next(I)->eraseFromParent(); 213198396Srdivacky Cond.clear(); 214276479Sdim FBB = nullptr; 215198396Srdivacky 216198396Srdivacky // Delete the JMP if it's equivalent to a fall-through. 217198396Srdivacky if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) { 218276479Sdim TBB = nullptr; 219198396Srdivacky I->eraseFromParent(); 220198396Srdivacky I = MBB.end(); 221198396Srdivacky continue; 222198396Srdivacky } 223198396Srdivacky 224198396Srdivacky // TBB is used to indicate the unconditinal destination. 225198396Srdivacky TBB = I->getOperand(0).getMBB(); 226198396Srdivacky continue; 227198396Srdivacky } 228198396Srdivacky 229198396Srdivacky // Handle conditional branches. 230198396Srdivacky assert(I->getOpcode() == MSP430::JCC && "Invalid conditional branch"); 231198396Srdivacky MSP430CC::CondCodes BranchCode = 232198396Srdivacky static_cast<MSP430CC::CondCodes>(I->getOperand(1).getImm()); 233198396Srdivacky if (BranchCode == MSP430CC::COND_INVALID) 234198396Srdivacky return true; // Can't handle weird stuff. 235198396Srdivacky 236198396Srdivacky // Working from the bottom, handle the first conditional branch. 237198396Srdivacky if (Cond.empty()) { 238198396Srdivacky FBB = TBB; 239198396Srdivacky TBB = I->getOperand(0).getMBB(); 240198396Srdivacky Cond.push_back(MachineOperand::CreateImm(BranchCode)); 241198396Srdivacky continue; 242198396Srdivacky } 243198396Srdivacky 244198396Srdivacky // Handle subsequent conditional branches. Only handle the case where all 245198396Srdivacky // conditional branches branch to the same destination. 246198396Srdivacky assert(Cond.size() == 1); 247198396Srdivacky assert(TBB); 248198396Srdivacky 249198396Srdivacky // Only handle the case where all conditional branches branch to 250198396Srdivacky // the same destination. 251198396Srdivacky if (TBB != I->getOperand(0).getMBB()) 252198396Srdivacky return true; 253198396Srdivacky 254198396Srdivacky MSP430CC::CondCodes OldBranchCode = (MSP430CC::CondCodes)Cond[0].getImm(); 255198396Srdivacky // If the conditions are the same, we can leave them alone. 256198396Srdivacky if (OldBranchCode == BranchCode) 257198396Srdivacky continue; 258198396Srdivacky 259198396Srdivacky return true; 260198396Srdivacky } 261198396Srdivacky 262198396Srdivacky return false; 263198396Srdivacky} 264198396Srdivacky 265314564Sdimunsigned MSP430InstrInfo::insertBranch(MachineBasicBlock &MBB, 266309124Sdim MachineBasicBlock *TBB, 267309124Sdim MachineBasicBlock *FBB, 268309124Sdim ArrayRef<MachineOperand> Cond, 269314564Sdim const DebugLoc &DL, 270314564Sdim int *BytesAdded) const { 271193323Sed // Shouldn't be a fall through. 272314564Sdim assert(TBB && "insertBranch must not be told to insert a fallthrough"); 273193323Sed assert((Cond.size() == 1 || Cond.size() == 0) && 274193323Sed "MSP430 branch conditions have one component!"); 275314564Sdim assert(!BytesAdded && "code size not handled"); 276193323Sed 277193323Sed if (Cond.empty()) { 278193323Sed // Unconditional branch? 279193323Sed assert(!FBB && "Unconditional branch with multiple successors!"); 280206124Srdivacky BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(TBB); 281193323Sed return 1; 282193323Sed } 283193323Sed 284193323Sed // Conditional branch. 285193323Sed unsigned Count = 0; 286206124Srdivacky BuildMI(&MBB, DL, get(MSP430::JCC)).addMBB(TBB).addImm(Cond[0].getImm()); 287198396Srdivacky ++Count; 288193323Sed 289198396Srdivacky if (FBB) { 290198396Srdivacky // Two-way Conditional branch. Insert the second branch. 291206124Srdivacky BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(FBB); 292198396Srdivacky ++Count; 293198396Srdivacky } 294193323Sed return Count; 295193323Sed} 296202878Srdivacky 297202878Srdivacky/// GetInstSize - Return the number of bytes of code the specified 298202878Srdivacky/// instruction may be. This returns the maximum number of bytes. 299202878Srdivacky/// 300314564Sdimunsigned MSP430InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const { 301309124Sdim const MCInstrDesc &Desc = MI.getDesc(); 302202878Srdivacky 303344779Sdim switch (Desc.getOpcode()) { 304344779Sdim case TargetOpcode::CFI_INSTRUCTION: 305344779Sdim case TargetOpcode::EH_LABEL: 306344779Sdim case TargetOpcode::IMPLICIT_DEF: 307344779Sdim case TargetOpcode::KILL: 308344779Sdim case TargetOpcode::DBG_VALUE: 309344779Sdim return 0; 310353358Sdim case TargetOpcode::INLINEASM: 311353358Sdim case TargetOpcode::INLINEASM_BR: { 312344779Sdim const MachineFunction *MF = MI.getParent()->getParent(); 313344779Sdim const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo(); 314344779Sdim return TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(), 315344779Sdim *MF->getTarget().getMCAsmInfo()); 316202878Srdivacky } 317344779Sdim } 318344779Sdim 319344779Sdim return Desc.getSize(); 320202878Srdivacky} 321