1 //===-- MSP430InstrInfo.cpp - MSP430 Instruction Information --------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains the MSP430 implementation of the TargetInstrInfo class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "MSP430InstrInfo.h" 14 #include "MSP430.h" 15 #include "MSP430MachineFunctionInfo.h" 16 #include "MSP430TargetMachine.h" 17 #include "llvm/CodeGen/MachineFrameInfo.h" 18 #include "llvm/CodeGen/MachineInstrBuilder.h" 19 #include "llvm/CodeGen/MachineRegisterInfo.h" 20 #include "llvm/IR/Function.h" 21 #include "llvm/Support/ErrorHandling.h" 22 #include "llvm/Support/TargetRegistry.h" 23 24 using namespace llvm; 25 26 #define GET_INSTRINFO_CTOR_DTOR 27 #include "MSP430GenInstrInfo.inc" 28 29 // Pin the vtable to this file. 30 void MSP430InstrInfo::anchor() {} 31 32 MSP430InstrInfo::MSP430InstrInfo(MSP430Subtarget &STI) 33 : MSP430GenInstrInfo(MSP430::ADJCALLSTACKDOWN, MSP430::ADJCALLSTACKUP), 34 RI() {} 35 36 void MSP430InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 37 MachineBasicBlock::iterator MI, 38 unsigned SrcReg, bool isKill, int FrameIdx, 39 const TargetRegisterClass *RC, 40 const TargetRegisterInfo *TRI) const { 41 DebugLoc DL; 42 if (MI != MBB.end()) DL = MI->getDebugLoc(); 43 MachineFunction &MF = *MBB.getParent(); 44 MachineFrameInfo &MFI = MF.getFrameInfo(); 45 46 MachineMemOperand *MMO = MF.getMachineMemOperand( 47 MachinePointerInfo::getFixedStack(MF, FrameIdx), 48 MachineMemOperand::MOStore, MFI.getObjectSize(FrameIdx), 49 MFI.getObjectAlignment(FrameIdx)); 50 51 if (RC == &MSP430::GR16RegClass) 52 BuildMI(MBB, MI, DL, get(MSP430::MOV16mr)) 53 .addFrameIndex(FrameIdx).addImm(0) 54 .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO); 55 else if (RC == &MSP430::GR8RegClass) 56 BuildMI(MBB, MI, DL, get(MSP430::MOV8mr)) 57 .addFrameIndex(FrameIdx).addImm(0) 58 .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO); 59 else 60 llvm_unreachable("Cannot store this register to stack slot!"); 61 } 62 63 void MSP430InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 64 MachineBasicBlock::iterator MI, 65 unsigned DestReg, int FrameIdx, 66 const TargetRegisterClass *RC, 67 const TargetRegisterInfo *TRI) const{ 68 DebugLoc DL; 69 if (MI != MBB.end()) DL = MI->getDebugLoc(); 70 MachineFunction &MF = *MBB.getParent(); 71 MachineFrameInfo &MFI = MF.getFrameInfo(); 72 73 MachineMemOperand *MMO = MF.getMachineMemOperand( 74 MachinePointerInfo::getFixedStack(MF, FrameIdx), 75 MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIdx), 76 MFI.getObjectAlignment(FrameIdx)); 77 78 if (RC == &MSP430::GR16RegClass) 79 BuildMI(MBB, MI, DL, get(MSP430::MOV16rm)) 80 .addReg(DestReg, getDefRegState(true)).addFrameIndex(FrameIdx) 81 .addImm(0).addMemOperand(MMO); 82 else if (RC == &MSP430::GR8RegClass) 83 BuildMI(MBB, MI, DL, get(MSP430::MOV8rm)) 84 .addReg(DestReg, getDefRegState(true)).addFrameIndex(FrameIdx) 85 .addImm(0).addMemOperand(MMO); 86 else 87 llvm_unreachable("Cannot store this register to stack slot!"); 88 } 89 90 void MSP430InstrInfo::copyPhysReg(MachineBasicBlock &MBB, 91 MachineBasicBlock::iterator I, 92 const DebugLoc &DL, unsigned DestReg, 93 unsigned SrcReg, bool KillSrc) const { 94 unsigned Opc; 95 if (MSP430::GR16RegClass.contains(DestReg, SrcReg)) 96 Opc = MSP430::MOV16rr; 97 else if (MSP430::GR8RegClass.contains(DestReg, SrcReg)) 98 Opc = MSP430::MOV8rr; 99 else 100 llvm_unreachable("Impossible reg-to-reg copy"); 101 102 BuildMI(MBB, I, DL, get(Opc), DestReg) 103 .addReg(SrcReg, getKillRegState(KillSrc)); 104 } 105 106 unsigned MSP430InstrInfo::removeBranch(MachineBasicBlock &MBB, 107 int *BytesRemoved) const { 108 assert(!BytesRemoved && "code size not handled"); 109 110 MachineBasicBlock::iterator I = MBB.end(); 111 unsigned Count = 0; 112 113 while (I != MBB.begin()) { 114 --I; 115 if (I->isDebugInstr()) 116 continue; 117 if (I->getOpcode() != MSP430::JMP && 118 I->getOpcode() != MSP430::JCC && 119 I->getOpcode() != MSP430::Br && 120 I->getOpcode() != MSP430::Bm) 121 break; 122 // Remove the branch. 123 I->eraseFromParent(); 124 I = MBB.end(); 125 ++Count; 126 } 127 128 return Count; 129 } 130 131 bool MSP430InstrInfo:: 132 reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 133 assert(Cond.size() == 1 && "Invalid Xbranch condition!"); 134 135 MSP430CC::CondCodes CC = static_cast<MSP430CC::CondCodes>(Cond[0].getImm()); 136 137 switch (CC) { 138 default: llvm_unreachable("Invalid branch condition!"); 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 163 bool MSP430InstrInfo::isUnpredicatedTerminator(const MachineInstr &MI) const { 164 if (!MI.isTerminator()) 165 return false; 166 167 // Conditional branch is a special case. 168 if (MI.isBranch() && !MI.isBarrier()) 169 return true; 170 if (!MI.isPredicable()) 171 return true; 172 return !isPredicated(MI); 173 } 174 175 bool 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->isDebugInstr()) 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->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 (std::next(I) != MBB.end()) 212 std::next(I)->eraseFromParent(); 213 Cond.clear(); 214 FBB = nullptr; 215 216 // Delete the JMP if it's equivalent to a fall-through. 217 if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) { 218 TBB = nullptr; 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 265 unsigned MSP430InstrInfo::insertBranch(MachineBasicBlock &MBB, 266 MachineBasicBlock *TBB, 267 MachineBasicBlock *FBB, 268 ArrayRef<MachineOperand> Cond, 269 const DebugLoc &DL, 270 int *BytesAdded) const { 271 // Shouldn't be a fall through. 272 assert(TBB && "insertBranch must not be told to insert a fallthrough"); 273 assert((Cond.size() == 1 || Cond.size() == 0) && 274 "MSP430 branch conditions have one component!"); 275 assert(!BytesAdded && "code size not handled"); 276 277 if (Cond.empty()) { 278 // Unconditional branch? 279 assert(!FBB && "Unconditional branch with multiple successors!"); 280 BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(TBB); 281 return 1; 282 } 283 284 // Conditional branch. 285 unsigned Count = 0; 286 BuildMI(&MBB, DL, get(MSP430::JCC)).addMBB(TBB).addImm(Cond[0].getImm()); 287 ++Count; 288 289 if (FBB) { 290 // Two-way Conditional branch. Insert the second branch. 291 BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(FBB); 292 ++Count; 293 } 294 return Count; 295 } 296 297 /// GetInstSize - Return the number of bytes of code the specified 298 /// instruction may be. This returns the maximum number of bytes. 299 /// 300 unsigned MSP430InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const { 301 const MCInstrDesc &Desc = MI.getDesc(); 302 303 switch (Desc.getOpcode()) { 304 case TargetOpcode::CFI_INSTRUCTION: 305 case TargetOpcode::EH_LABEL: 306 case TargetOpcode::IMPLICIT_DEF: 307 case TargetOpcode::KILL: 308 case TargetOpcode::DBG_VALUE: 309 return 0; 310 case TargetOpcode::INLINEASM: 311 case TargetOpcode::INLINEASM_BR: { 312 const MachineFunction *MF = MI.getParent()->getParent(); 313 const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo(); 314 return TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(), 315 *MF->getTarget().getMCAsmInfo()); 316 } 317 } 318 319 return Desc.getSize(); 320 } 321