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