109467b48Spatrick //===-- MSP430InstrInfo.cpp - MSP430 Instruction Information --------------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This file contains the MSP430 implementation of the TargetInstrInfo class.
1009467b48Spatrick //
1109467b48Spatrick //===----------------------------------------------------------------------===//
1209467b48Spatrick 
1309467b48Spatrick #include "MSP430InstrInfo.h"
1409467b48Spatrick #include "MSP430.h"
1509467b48Spatrick #include "MSP430MachineFunctionInfo.h"
1609467b48Spatrick #include "MSP430TargetMachine.h"
1709467b48Spatrick #include "llvm/CodeGen/MachineFrameInfo.h"
1809467b48Spatrick #include "llvm/CodeGen/MachineInstrBuilder.h"
1909467b48Spatrick #include "llvm/CodeGen/MachineRegisterInfo.h"
2009467b48Spatrick #include "llvm/IR/Function.h"
21*d415bd75Srobert #include "llvm/MC/TargetRegistry.h"
2209467b48Spatrick #include "llvm/Support/ErrorHandling.h"
2309467b48Spatrick 
2409467b48Spatrick using namespace llvm;
2509467b48Spatrick 
2609467b48Spatrick #define GET_INSTRINFO_CTOR_DTOR
2709467b48Spatrick #include "MSP430GenInstrInfo.inc"
2809467b48Spatrick 
2909467b48Spatrick // Pin the vtable to this file.
anchor()3009467b48Spatrick void MSP430InstrInfo::anchor() {}
3109467b48Spatrick 
MSP430InstrInfo(MSP430Subtarget & STI)3209467b48Spatrick MSP430InstrInfo::MSP430InstrInfo(MSP430Subtarget &STI)
3309467b48Spatrick   : MSP430GenInstrInfo(MSP430::ADJCALLSTACKDOWN, MSP430::ADJCALLSTACKUP),
3409467b48Spatrick     RI() {}
3509467b48Spatrick 
storeRegToStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,Register SrcReg,bool isKill,int FrameIdx,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI,Register VReg) const36*d415bd75Srobert void MSP430InstrInfo::storeRegToStackSlot(
37*d415bd75Srobert     MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg,
38*d415bd75Srobert     bool isKill, int FrameIdx, const TargetRegisterClass *RC,
39*d415bd75Srobert     const TargetRegisterInfo *TRI, Register VReg) const {
4009467b48Spatrick   DebugLoc DL;
4109467b48Spatrick   if (MI != MBB.end()) DL = MI->getDebugLoc();
4209467b48Spatrick   MachineFunction &MF = *MBB.getParent();
4309467b48Spatrick   MachineFrameInfo &MFI = MF.getFrameInfo();
4409467b48Spatrick 
4509467b48Spatrick   MachineMemOperand *MMO = MF.getMachineMemOperand(
4609467b48Spatrick       MachinePointerInfo::getFixedStack(MF, FrameIdx),
4709467b48Spatrick       MachineMemOperand::MOStore, MFI.getObjectSize(FrameIdx),
48097a140dSpatrick       MFI.getObjectAlign(FrameIdx));
4909467b48Spatrick 
5009467b48Spatrick   if (RC == &MSP430::GR16RegClass)
5109467b48Spatrick     BuildMI(MBB, MI, DL, get(MSP430::MOV16mr))
5209467b48Spatrick       .addFrameIndex(FrameIdx).addImm(0)
5309467b48Spatrick       .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
5409467b48Spatrick   else if (RC == &MSP430::GR8RegClass)
5509467b48Spatrick     BuildMI(MBB, MI, DL, get(MSP430::MOV8mr))
5609467b48Spatrick       .addFrameIndex(FrameIdx).addImm(0)
5709467b48Spatrick       .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
5809467b48Spatrick   else
5909467b48Spatrick     llvm_unreachable("Cannot store this register to stack slot!");
6009467b48Spatrick }
6109467b48Spatrick 
loadRegFromStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,Register DestReg,int FrameIdx,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI,Register VReg) const6209467b48Spatrick void MSP430InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
6309467b48Spatrick                                            MachineBasicBlock::iterator MI,
64097a140dSpatrick                                            Register DestReg, int FrameIdx,
6509467b48Spatrick                                            const TargetRegisterClass *RC,
66*d415bd75Srobert                                            const TargetRegisterInfo *TRI,
67*d415bd75Srobert                                            Register VReg) const {
6809467b48Spatrick   DebugLoc DL;
6909467b48Spatrick   if (MI != MBB.end()) DL = MI->getDebugLoc();
7009467b48Spatrick   MachineFunction &MF = *MBB.getParent();
7109467b48Spatrick   MachineFrameInfo &MFI = MF.getFrameInfo();
7209467b48Spatrick 
7309467b48Spatrick   MachineMemOperand *MMO = MF.getMachineMemOperand(
7409467b48Spatrick       MachinePointerInfo::getFixedStack(MF, FrameIdx),
7509467b48Spatrick       MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIdx),
76097a140dSpatrick       MFI.getObjectAlign(FrameIdx));
7709467b48Spatrick 
7809467b48Spatrick   if (RC == &MSP430::GR16RegClass)
7909467b48Spatrick     BuildMI(MBB, MI, DL, get(MSP430::MOV16rm))
8009467b48Spatrick       .addReg(DestReg, getDefRegState(true)).addFrameIndex(FrameIdx)
8109467b48Spatrick       .addImm(0).addMemOperand(MMO);
8209467b48Spatrick   else if (RC == &MSP430::GR8RegClass)
8309467b48Spatrick     BuildMI(MBB, MI, DL, get(MSP430::MOV8rm))
8409467b48Spatrick       .addReg(DestReg, getDefRegState(true)).addFrameIndex(FrameIdx)
8509467b48Spatrick       .addImm(0).addMemOperand(MMO);
8609467b48Spatrick   else
8709467b48Spatrick     llvm_unreachable("Cannot store this register to stack slot!");
8809467b48Spatrick }
8909467b48Spatrick 
copyPhysReg(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,const DebugLoc & DL,MCRegister DestReg,MCRegister SrcReg,bool KillSrc) const9009467b48Spatrick void MSP430InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
9109467b48Spatrick                                   MachineBasicBlock::iterator I,
9209467b48Spatrick                                   const DebugLoc &DL, MCRegister DestReg,
9309467b48Spatrick                                   MCRegister SrcReg, bool KillSrc) const {
9409467b48Spatrick   unsigned Opc;
9509467b48Spatrick   if (MSP430::GR16RegClass.contains(DestReg, SrcReg))
9609467b48Spatrick     Opc = MSP430::MOV16rr;
9709467b48Spatrick   else if (MSP430::GR8RegClass.contains(DestReg, SrcReg))
9809467b48Spatrick     Opc = MSP430::MOV8rr;
9909467b48Spatrick   else
10009467b48Spatrick     llvm_unreachable("Impossible reg-to-reg copy");
10109467b48Spatrick 
10209467b48Spatrick   BuildMI(MBB, I, DL, get(Opc), DestReg)
10309467b48Spatrick     .addReg(SrcReg, getKillRegState(KillSrc));
10409467b48Spatrick }
10509467b48Spatrick 
removeBranch(MachineBasicBlock & MBB,int * BytesRemoved) const10609467b48Spatrick unsigned MSP430InstrInfo::removeBranch(MachineBasicBlock &MBB,
10709467b48Spatrick                                        int *BytesRemoved) const {
10809467b48Spatrick   assert(!BytesRemoved && "code size not handled");
10909467b48Spatrick 
11009467b48Spatrick   MachineBasicBlock::iterator I = MBB.end();
11109467b48Spatrick   unsigned Count = 0;
11209467b48Spatrick 
11309467b48Spatrick   while (I != MBB.begin()) {
11409467b48Spatrick     --I;
11509467b48Spatrick     if (I->isDebugInstr())
11609467b48Spatrick       continue;
11709467b48Spatrick     if (I->getOpcode() != MSP430::JMP &&
11809467b48Spatrick         I->getOpcode() != MSP430::JCC &&
119*d415bd75Srobert         I->getOpcode() != MSP430::Bi &&
12009467b48Spatrick         I->getOpcode() != MSP430::Br &&
12109467b48Spatrick         I->getOpcode() != MSP430::Bm)
12209467b48Spatrick       break;
12309467b48Spatrick     // Remove the branch.
12409467b48Spatrick     I->eraseFromParent();
12509467b48Spatrick     I = MBB.end();
12609467b48Spatrick     ++Count;
12709467b48Spatrick   }
12809467b48Spatrick 
12909467b48Spatrick   return Count;
13009467b48Spatrick }
13109467b48Spatrick 
13209467b48Spatrick bool MSP430InstrInfo::
reverseBranchCondition(SmallVectorImpl<MachineOperand> & Cond) const13309467b48Spatrick reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
13409467b48Spatrick   assert(Cond.size() == 1 && "Invalid Xbranch condition!");
13509467b48Spatrick 
13609467b48Spatrick   MSP430CC::CondCodes CC = static_cast<MSP430CC::CondCodes>(Cond[0].getImm());
13709467b48Spatrick 
13809467b48Spatrick   switch (CC) {
13909467b48Spatrick   default: llvm_unreachable("Invalid branch condition!");
14009467b48Spatrick   case MSP430CC::COND_E:
14109467b48Spatrick     CC = MSP430CC::COND_NE;
14209467b48Spatrick     break;
14309467b48Spatrick   case MSP430CC::COND_NE:
14409467b48Spatrick     CC = MSP430CC::COND_E;
14509467b48Spatrick     break;
14609467b48Spatrick   case MSP430CC::COND_L:
14709467b48Spatrick     CC = MSP430CC::COND_GE;
14809467b48Spatrick     break;
14909467b48Spatrick   case MSP430CC::COND_GE:
15009467b48Spatrick     CC = MSP430CC::COND_L;
15109467b48Spatrick     break;
15209467b48Spatrick   case MSP430CC::COND_HS:
15309467b48Spatrick     CC = MSP430CC::COND_LO;
15409467b48Spatrick     break;
15509467b48Spatrick   case MSP430CC::COND_LO:
15609467b48Spatrick     CC = MSP430CC::COND_HS;
15709467b48Spatrick     break;
15809467b48Spatrick   }
15909467b48Spatrick 
16009467b48Spatrick   Cond[0].setImm(CC);
16109467b48Spatrick   return false;
16209467b48Spatrick }
16309467b48Spatrick 
analyzeBranch(MachineBasicBlock & MBB,MachineBasicBlock * & TBB,MachineBasicBlock * & FBB,SmallVectorImpl<MachineOperand> & Cond,bool AllowModify) const16409467b48Spatrick bool MSP430InstrInfo::analyzeBranch(MachineBasicBlock &MBB,
16509467b48Spatrick                                     MachineBasicBlock *&TBB,
16609467b48Spatrick                                     MachineBasicBlock *&FBB,
16709467b48Spatrick                                     SmallVectorImpl<MachineOperand> &Cond,
16809467b48Spatrick                                     bool AllowModify) const {
16909467b48Spatrick   // Start from the bottom of the block and work up, examining the
17009467b48Spatrick   // terminator instructions.
17109467b48Spatrick   MachineBasicBlock::iterator I = MBB.end();
17209467b48Spatrick   while (I != MBB.begin()) {
17309467b48Spatrick     --I;
17409467b48Spatrick     if (I->isDebugInstr())
17509467b48Spatrick       continue;
17609467b48Spatrick 
17709467b48Spatrick     // Working from the bottom, when we see a non-terminator
17809467b48Spatrick     // instruction, we're done.
17909467b48Spatrick     if (!isUnpredicatedTerminator(*I))
18009467b48Spatrick       break;
18109467b48Spatrick 
18209467b48Spatrick     // A terminator that isn't a branch can't easily be handled
18309467b48Spatrick     // by this analysis.
18409467b48Spatrick     if (!I->isBranch())
18509467b48Spatrick       return true;
18609467b48Spatrick 
18709467b48Spatrick     // Cannot handle indirect branches.
18809467b48Spatrick     if (I->getOpcode() == MSP430::Br ||
18909467b48Spatrick         I->getOpcode() == MSP430::Bm)
19009467b48Spatrick       return true;
19109467b48Spatrick 
19209467b48Spatrick     // Handle unconditional branches.
193*d415bd75Srobert     if (I->getOpcode() == MSP430::JMP || I->getOpcode() == MSP430::Bi) {
19409467b48Spatrick       if (!AllowModify) {
19509467b48Spatrick         TBB = I->getOperand(0).getMBB();
19609467b48Spatrick         continue;
19709467b48Spatrick       }
19809467b48Spatrick 
19909467b48Spatrick       // If the block has any instructions after a JMP, delete them.
200*d415bd75Srobert       MBB.erase(std::next(I), MBB.end());
20109467b48Spatrick       Cond.clear();
20209467b48Spatrick       FBB = nullptr;
20309467b48Spatrick 
20409467b48Spatrick       // Delete the JMP if it's equivalent to a fall-through.
20509467b48Spatrick       if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
20609467b48Spatrick         TBB = nullptr;
20709467b48Spatrick         I->eraseFromParent();
20809467b48Spatrick         I = MBB.end();
20909467b48Spatrick         continue;
21009467b48Spatrick       }
21109467b48Spatrick 
21209467b48Spatrick       // TBB is used to indicate the unconditinal destination.
21309467b48Spatrick       TBB = I->getOperand(0).getMBB();
21409467b48Spatrick       continue;
21509467b48Spatrick     }
21609467b48Spatrick 
21709467b48Spatrick     // Handle conditional branches.
21809467b48Spatrick     assert(I->getOpcode() == MSP430::JCC && "Invalid conditional branch");
21909467b48Spatrick     MSP430CC::CondCodes BranchCode =
22009467b48Spatrick       static_cast<MSP430CC::CondCodes>(I->getOperand(1).getImm());
22109467b48Spatrick     if (BranchCode == MSP430CC::COND_INVALID)
22209467b48Spatrick       return true;  // Can't handle weird stuff.
22309467b48Spatrick 
22409467b48Spatrick     // Working from the bottom, handle the first conditional branch.
22509467b48Spatrick     if (Cond.empty()) {
22609467b48Spatrick       FBB = TBB;
22709467b48Spatrick       TBB = I->getOperand(0).getMBB();
22809467b48Spatrick       Cond.push_back(MachineOperand::CreateImm(BranchCode));
22909467b48Spatrick       continue;
23009467b48Spatrick     }
23109467b48Spatrick 
23209467b48Spatrick     // Handle subsequent conditional branches. Only handle the case where all
23309467b48Spatrick     // conditional branches branch to the same destination.
23409467b48Spatrick     assert(Cond.size() == 1);
23509467b48Spatrick     assert(TBB);
23609467b48Spatrick 
23709467b48Spatrick     // Only handle the case where all conditional branches branch to
23809467b48Spatrick     // the same destination.
23909467b48Spatrick     if (TBB != I->getOperand(0).getMBB())
24009467b48Spatrick       return true;
24109467b48Spatrick 
24209467b48Spatrick     MSP430CC::CondCodes OldBranchCode = (MSP430CC::CondCodes)Cond[0].getImm();
24309467b48Spatrick     // If the conditions are the same, we can leave them alone.
24409467b48Spatrick     if (OldBranchCode == BranchCode)
24509467b48Spatrick       continue;
24609467b48Spatrick 
24709467b48Spatrick     return true;
24809467b48Spatrick   }
24909467b48Spatrick 
25009467b48Spatrick   return false;
25109467b48Spatrick }
25209467b48Spatrick 
insertBranch(MachineBasicBlock & MBB,MachineBasicBlock * TBB,MachineBasicBlock * FBB,ArrayRef<MachineOperand> Cond,const DebugLoc & DL,int * BytesAdded) const25309467b48Spatrick unsigned MSP430InstrInfo::insertBranch(MachineBasicBlock &MBB,
25409467b48Spatrick                                        MachineBasicBlock *TBB,
25509467b48Spatrick                                        MachineBasicBlock *FBB,
25609467b48Spatrick                                        ArrayRef<MachineOperand> Cond,
25709467b48Spatrick                                        const DebugLoc &DL,
25809467b48Spatrick                                        int *BytesAdded) const {
25909467b48Spatrick   // Shouldn't be a fall through.
26009467b48Spatrick   assert(TBB && "insertBranch must not be told to insert a fallthrough");
26109467b48Spatrick   assert((Cond.size() == 1 || Cond.size() == 0) &&
26209467b48Spatrick          "MSP430 branch conditions have one component!");
26309467b48Spatrick   assert(!BytesAdded && "code size not handled");
26409467b48Spatrick 
26509467b48Spatrick   if (Cond.empty()) {
26609467b48Spatrick     // Unconditional branch?
26709467b48Spatrick     assert(!FBB && "Unconditional branch with multiple successors!");
26809467b48Spatrick     BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(TBB);
26909467b48Spatrick     return 1;
27009467b48Spatrick   }
27109467b48Spatrick 
27209467b48Spatrick   // Conditional branch.
27309467b48Spatrick   unsigned Count = 0;
27409467b48Spatrick   BuildMI(&MBB, DL, get(MSP430::JCC)).addMBB(TBB).addImm(Cond[0].getImm());
27509467b48Spatrick   ++Count;
27609467b48Spatrick 
27709467b48Spatrick   if (FBB) {
27809467b48Spatrick     // Two-way Conditional branch. Insert the second branch.
27909467b48Spatrick     BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(FBB);
28009467b48Spatrick     ++Count;
28109467b48Spatrick   }
28209467b48Spatrick   return Count;
28309467b48Spatrick }
28409467b48Spatrick 
28509467b48Spatrick /// GetInstSize - Return the number of bytes of code the specified
28609467b48Spatrick /// instruction may be.  This returns the maximum number of bytes.
28709467b48Spatrick ///
getInstSizeInBytes(const MachineInstr & MI) const28809467b48Spatrick unsigned MSP430InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
28909467b48Spatrick   const MCInstrDesc &Desc = MI.getDesc();
29009467b48Spatrick 
29109467b48Spatrick   switch (Desc.getOpcode()) {
29209467b48Spatrick   case TargetOpcode::CFI_INSTRUCTION:
29309467b48Spatrick   case TargetOpcode::EH_LABEL:
29409467b48Spatrick   case TargetOpcode::IMPLICIT_DEF:
29509467b48Spatrick   case TargetOpcode::KILL:
29609467b48Spatrick   case TargetOpcode::DBG_VALUE:
29709467b48Spatrick     return 0;
29809467b48Spatrick   case TargetOpcode::INLINEASM:
29909467b48Spatrick   case TargetOpcode::INLINEASM_BR: {
30009467b48Spatrick     const MachineFunction *MF = MI.getParent()->getParent();
30109467b48Spatrick     const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
30209467b48Spatrick     return TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(),
30309467b48Spatrick                                   *MF->getTarget().getMCAsmInfo());
30409467b48Spatrick   }
30509467b48Spatrick   }
30609467b48Spatrick 
30709467b48Spatrick   return Desc.getSize();
30809467b48Spatrick }
309