131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- MSP430InstrInfo.cpp - MSP430 Instruction Information --------------===//
2f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//
3f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//                     The LLVM Compiler Infrastructure
4f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//
5f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// This file is distributed under the University of Illinois Open Source
6f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// License. See LICENSE.TXT for details.
7f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//
8f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//===----------------------------------------------------------------------===//
9f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//
10f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// This file contains the MSP430 implementation of the TargetInstrInfo class.
11f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//
12f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//===----------------------------------------------------------------------===//
13f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
14f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430InstrInfo.h"
1579aa3417eb6f58d668aadfedf075240a41d35a26Craig Topper#include "MSP430.h"
16d5047cb9f7f207798e1729911daa6d3752b668e3Anton Korobeynikov#include "MSP430MachineFunctionInfo.h"
17f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430TargetMachine.h"
18aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h"
19f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h"
20f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineRegisterInfo.h"
210b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h"
22c25e7581b9b8088910da31702d4ca21c4734c6d7Torok Edwin#include "llvm/Support/ErrorHandling.h"
233e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h"
24f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
254db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng#define GET_INSTRINFO_CTOR
2622fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng#include "MSP430GenInstrInfo.inc"
2722fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
28f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovusing namespace llvm;
29f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
30f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovMSP430InstrInfo::MSP430InstrInfo(MSP430TargetMachine &tm)
314db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng  : MSP430GenInstrInfo(MSP430::ADJCALLSTACKDOWN, MSP430::ADJCALLSTACKUP),
32a7542d5f870c5d98960d1676e23ac1d1d975d7e5Benjamin Kramer    RI(tm, *this) {}
331df221f2bb8e8380e255d1bec73ab07b388d01a2Anton Korobeynikov
34aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikovvoid MSP430InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
35aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov                                          MachineBasicBlock::iterator MI,
36aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov                                    unsigned SrcReg, bool isKill, int FrameIdx,
37746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng                                          const TargetRegisterClass *RC,
38746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng                                          const TargetRegisterInfo *TRI) const {
39c7f3ace20c325521c68335a1689645b43b06ddf0Chris Lattner  DebugLoc DL;
40aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  if (MI != MBB.end()) DL = MI->getDebugLoc();
418046ef4379c8a1f98d9f05e34fa55285e1c9582cAnton Korobeynikov  MachineFunction &MF = *MBB.getParent();
428046ef4379c8a1f98d9f05e34fa55285e1c9582cAnton Korobeynikov  MachineFrameInfo &MFI = *MF.getFrameInfo();
438046ef4379c8a1f98d9f05e34fa55285e1c9582cAnton Korobeynikov
448046ef4379c8a1f98d9f05e34fa55285e1c9582cAnton Korobeynikov  MachineMemOperand *MMO =
45978e0dfe46e481bfb1281e683aa308329e879e95Jay Foad    MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIdx),
4659db5496f4fc2ef6111569e542f8b65480ef14c1Chris Lattner                            MachineMemOperand::MOStore,
478046ef4379c8a1f98d9f05e34fa55285e1c9582cAnton Korobeynikov                            MFI.getObjectSize(FrameIdx),
488046ef4379c8a1f98d9f05e34fa55285e1c9582cAnton Korobeynikov                            MFI.getObjectAlignment(FrameIdx));
49aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
50aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  if (RC == &MSP430::GR16RegClass)
51aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov    BuildMI(MBB, MI, DL, get(MSP430::MOV16mr))
52aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov      .addFrameIndex(FrameIdx).addImm(0)
538046ef4379c8a1f98d9f05e34fa55285e1c9582cAnton Korobeynikov      .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
54aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  else if (RC == &MSP430::GR8RegClass)
55aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov    BuildMI(MBB, MI, DL, get(MSP430::MOV8mr))
56aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov      .addFrameIndex(FrameIdx).addImm(0)
578046ef4379c8a1f98d9f05e34fa55285e1c9582cAnton Korobeynikov      .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
58aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  else
59c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Cannot store this register to stack slot!");
60aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov}
61aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
62aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikovvoid MSP430InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
63aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov                                           MachineBasicBlock::iterator MI,
64aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov                                           unsigned DestReg, int FrameIdx,
65746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng                                           const TargetRegisterClass *RC,
66746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng                                           const TargetRegisterInfo *TRI) const{
67c7f3ace20c325521c68335a1689645b43b06ddf0Chris Lattner  DebugLoc DL;
68aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  if (MI != MBB.end()) DL = MI->getDebugLoc();
698046ef4379c8a1f98d9f05e34fa55285e1c9582cAnton Korobeynikov  MachineFunction &MF = *MBB.getParent();
708046ef4379c8a1f98d9f05e34fa55285e1c9582cAnton Korobeynikov  MachineFrameInfo &MFI = *MF.getFrameInfo();
718046ef4379c8a1f98d9f05e34fa55285e1c9582cAnton Korobeynikov
728046ef4379c8a1f98d9f05e34fa55285e1c9582cAnton Korobeynikov  MachineMemOperand *MMO =
73978e0dfe46e481bfb1281e683aa308329e879e95Jay Foad    MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIdx),
7459db5496f4fc2ef6111569e542f8b65480ef14c1Chris Lattner                            MachineMemOperand::MOLoad,
758046ef4379c8a1f98d9f05e34fa55285e1c9582cAnton Korobeynikov                            MFI.getObjectSize(FrameIdx),
768046ef4379c8a1f98d9f05e34fa55285e1c9582cAnton Korobeynikov                            MFI.getObjectAlignment(FrameIdx));
77aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
78aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  if (RC == &MSP430::GR16RegClass)
79aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov    BuildMI(MBB, MI, DL, get(MSP430::MOV16rm))
808046ef4379c8a1f98d9f05e34fa55285e1c9582cAnton Korobeynikov      .addReg(DestReg).addFrameIndex(FrameIdx).addImm(0).addMemOperand(MMO);
81aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  else if (RC == &MSP430::GR8RegClass)
82aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov    BuildMI(MBB, MI, DL, get(MSP430::MOV8rm))
838046ef4379c8a1f98d9f05e34fa55285e1c9582cAnton Korobeynikov      .addReg(DestReg).addFrameIndex(FrameIdx).addImm(0).addMemOperand(MMO);
84aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov  else
85c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Cannot store this register to stack slot!");
86aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov}
87aa29915b5822bd9af2a2b80eb95be59368743935Anton Korobeynikov
8841ce3cfd1b726979d09401d7f030be94c7b33f66Jakob Stoklund Olesenvoid MSP430InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
8941ce3cfd1b726979d09401d7f030be94c7b33f66Jakob Stoklund Olesen                                  MachineBasicBlock::iterator I, DebugLoc DL,
9041ce3cfd1b726979d09401d7f030be94c7b33f66Jakob Stoklund Olesen                                  unsigned DestReg, unsigned SrcReg,
9141ce3cfd1b726979d09401d7f030be94c7b33f66Jakob Stoklund Olesen                                  bool KillSrc) const {
9241ce3cfd1b726979d09401d7f030be94c7b33f66Jakob Stoklund Olesen  unsigned Opc;
9341ce3cfd1b726979d09401d7f030be94c7b33f66Jakob Stoklund Olesen  if (MSP430::GR16RegClass.contains(DestReg, SrcReg))
9441ce3cfd1b726979d09401d7f030be94c7b33f66Jakob Stoklund Olesen    Opc = MSP430::MOV16rr;
9541ce3cfd1b726979d09401d7f030be94c7b33f66Jakob Stoklund Olesen  else if (MSP430::GR8RegClass.contains(DestReg, SrcReg))
9641ce3cfd1b726979d09401d7f030be94c7b33f66Jakob Stoklund Olesen    Opc = MSP430::MOV8rr;
9741ce3cfd1b726979d09401d7f030be94c7b33f66Jakob Stoklund Olesen  else
9841ce3cfd1b726979d09401d7f030be94c7b33f66Jakob Stoklund Olesen    llvm_unreachable("Impossible reg-to-reg copy");
9951c31d6888a6c2a7cea74e210a1e1c8551535f28Anton Korobeynikov
10041ce3cfd1b726979d09401d7f030be94c7b33f66Jakob Stoklund Olesen  BuildMI(MBB, I, DL, get(Opc), DestReg)
10141ce3cfd1b726979d09401d7f030be94c7b33f66Jakob Stoklund Olesen    .addReg(SrcReg, getKillRegState(KillSrc));
1021df221f2bb8e8380e255d1bec73ab07b388d01a2Anton Korobeynikov}
1031df221f2bb8e8380e255d1bec73ab07b388d01a2Anton Korobeynikov
10490593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikovunsigned MSP430InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
10590593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  MachineBasicBlock::iterator I = MBB.end();
10690593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  unsigned Count = 0;
10790593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov
10890593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  while (I != MBB.begin()) {
10990593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    --I;
11093d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen    if (I->isDebugValue())
11193d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen      continue;
11290593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    if (I->getOpcode() != MSP430::JMP &&
11369d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov        I->getOpcode() != MSP430::JCC &&
11469d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov        I->getOpcode() != MSP430::Br &&
11569d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov        I->getOpcode() != MSP430::Bm)
11690593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov      break;
11790593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    // Remove the branch.
11890593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    I->eraseFromParent();
11990593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    I = MBB.end();
12090593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    ++Count;
12190593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  }
12290593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov
12390593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  return Count;
12490593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov}
12590593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov
12690593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikovbool MSP430InstrInfo::
12790593d2e1f31fd1c3be353b836b50280c3a6d243Anton KorobeynikovReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
12890593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  assert(Cond.size() == 1 && "Invalid Xbranch condition!");
12990593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov
13090593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  MSP430CC::CondCodes CC = static_cast<MSP430CC::CondCodes>(Cond[0].getImm());
13190593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov
13290593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  switch (CC) {
133bc2198133a1836598b54b943420748e75d5dea94Craig Topper  default: llvm_unreachable("Invalid branch condition!");
13490593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  case MSP430CC::COND_E:
13590593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    CC = MSP430CC::COND_NE;
13690593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    break;
13790593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  case MSP430CC::COND_NE:
13890593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    CC = MSP430CC::COND_E;
13990593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    break;
14090593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  case MSP430CC::COND_L:
14190593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    CC = MSP430CC::COND_GE;
14290593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    break;
14390593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  case MSP430CC::COND_GE:
14490593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    CC = MSP430CC::COND_L;
14590593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    break;
14690593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  case MSP430CC::COND_HS:
14790593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    CC = MSP430CC::COND_LO;
14890593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    break;
14990593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  case MSP430CC::COND_LO:
15090593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    CC = MSP430CC::COND_HS;
15190593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    break;
15290593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  }
15390593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov
15490593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  Cond[0].setImm(CC);
15590593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  return false;
15690593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov}
15790593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov
15890593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikovbool MSP430InstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
1595a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng  if (!MI->isTerminator()) return false;
16090593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov
16190593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  // Conditional branch is a special case.
1625a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng  if (MI->isBranch() && !MI->isBarrier())
16390593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    return true;
1645a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng  if (!MI->isPredicable())
16590593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    return true;
16690593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  return !isPredicated(MI);
16790593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov}
16890593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov
16990593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikovbool MSP430InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
17090593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov                                    MachineBasicBlock *&TBB,
17190593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov                                    MachineBasicBlock *&FBB,
17290593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov                                    SmallVectorImpl<MachineOperand> &Cond,
17390593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov                                    bool AllowModify) const {
17490593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  // Start from the bottom of the block and work up, examining the
17590593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  // terminator instructions.
17690593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  MachineBasicBlock::iterator I = MBB.end();
17790593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  while (I != MBB.begin()) {
17890593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    --I;
17993d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen    if (I->isDebugValue())
18093d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen      continue;
18193d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen
18290593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    // Working from the bottom, when we see a non-terminator
18390593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    // instruction, we're done.
18490593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    if (!isUnpredicatedTerminator(I))
18590593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov      break;
18690593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov
18790593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    // A terminator that isn't a branch can't easily be handled
18890593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    // by this analysis.
1895a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng    if (!I->isBranch())
19090593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov      return true;
19190593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov
19269d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov    // Cannot handle indirect branches.
19369d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov    if (I->getOpcode() == MSP430::Br ||
19469d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov        I->getOpcode() == MSP430::Bm)
19569d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov      return true;
19669d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov
19790593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    // Handle unconditional branches.
19890593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    if (I->getOpcode() == MSP430::JMP) {
19990593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov      if (!AllowModify) {
20090593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov        TBB = I->getOperand(0).getMBB();
20190593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov        continue;
20290593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov      }
20390593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov
20490593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov      // If the block has any instructions after a JMP, delete them.
2057896c9f436a4eda5ec15e882a7505ba482a2fcd0Chris Lattner      while (llvm::next(I) != MBB.end())
2067896c9f436a4eda5ec15e882a7505ba482a2fcd0Chris Lattner        llvm::next(I)->eraseFromParent();
20790593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov      Cond.clear();
20890593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov      FBB = 0;
20990593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov
21090593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov      // Delete the JMP if it's equivalent to a fall-through.
21190593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov      if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
21290593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov        TBB = 0;
21390593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov        I->eraseFromParent();
21490593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov        I = MBB.end();
21590593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov        continue;
21690593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov      }
21790593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov
21890593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov      // TBB is used to indicate the unconditinal destination.
21990593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov      TBB = I->getOperand(0).getMBB();
22090593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov      continue;
22190593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    }
22290593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov
22390593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    // Handle conditional branches.
22490593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    assert(I->getOpcode() == MSP430::JCC && "Invalid conditional branch");
22590593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    MSP430CC::CondCodes BranchCode =
22690593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov      static_cast<MSP430CC::CondCodes>(I->getOperand(1).getImm());
22790593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    if (BranchCode == MSP430CC::COND_INVALID)
22890593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov      return true;  // Can't handle weird stuff.
22990593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov
23090593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    // Working from the bottom, handle the first conditional branch.
23190593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    if (Cond.empty()) {
23290593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov      FBB = TBB;
23390593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov      TBB = I->getOperand(0).getMBB();
23490593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov      Cond.push_back(MachineOperand::CreateImm(BranchCode));
23590593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov      continue;
23690593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    }
23790593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov
23890593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    // Handle subsequent conditional branches. Only handle the case where all
23990593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    // conditional branches branch to the same destination.
24090593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    assert(Cond.size() == 1);
24190593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    assert(TBB);
24290593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov
24390593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    // Only handle the case where all conditional branches branch to
24490593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    // the same destination.
24590593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    if (TBB != I->getOperand(0).getMBB())
24690593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov      return true;
24790593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov
24890593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    MSP430CC::CondCodes OldBranchCode = (MSP430CC::CondCodes)Cond[0].getImm();
24990593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    // If the conditions are the same, we can leave them alone.
25090593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    if (OldBranchCode == BranchCode)
25190593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov      continue;
25290593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov
25390593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    return true;
25490593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  }
25590593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov
25690593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  return false;
25790593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov}
25890593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov
2598644af36903d933b6f9ae80d2d51b9e340c48452Anton Korobeynikovunsigned
2608644af36903d933b6f9ae80d2d51b9e340c48452Anton KorobeynikovMSP430InstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
2618644af36903d933b6f9ae80d2d51b9e340c48452Anton Korobeynikov                              MachineBasicBlock *FBB,
2623bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings                              const SmallVectorImpl<MachineOperand> &Cond,
2633bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings                              DebugLoc DL) const {
2648644af36903d933b6f9ae80d2d51b9e340c48452Anton Korobeynikov  // Shouldn't be a fall through.
2658644af36903d933b6f9ae80d2d51b9e340c48452Anton Korobeynikov  assert(TBB && "InsertBranch must not be told to insert a fallthrough");
2668644af36903d933b6f9ae80d2d51b9e340c48452Anton Korobeynikov  assert((Cond.size() == 1 || Cond.size() == 0) &&
2678644af36903d933b6f9ae80d2d51b9e340c48452Anton Korobeynikov         "MSP430 branch conditions have one component!");
2688644af36903d933b6f9ae80d2d51b9e340c48452Anton Korobeynikov
2698644af36903d933b6f9ae80d2d51b9e340c48452Anton Korobeynikov  if (Cond.empty()) {
2708644af36903d933b6f9ae80d2d51b9e340c48452Anton Korobeynikov    // Unconditional branch?
2718644af36903d933b6f9ae80d2d51b9e340c48452Anton Korobeynikov    assert(!FBB && "Unconditional branch with multiple successors!");
272c7f3ace20c325521c68335a1689645b43b06ddf0Chris Lattner    BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(TBB);
2738644af36903d933b6f9ae80d2d51b9e340c48452Anton Korobeynikov    return 1;
2748644af36903d933b6f9ae80d2d51b9e340c48452Anton Korobeynikov  }
2758644af36903d933b6f9ae80d2d51b9e340c48452Anton Korobeynikov
2768644af36903d933b6f9ae80d2d51b9e340c48452Anton Korobeynikov  // Conditional branch.
2778644af36903d933b6f9ae80d2d51b9e340c48452Anton Korobeynikov  unsigned Count = 0;
278c7f3ace20c325521c68335a1689645b43b06ddf0Chris Lattner  BuildMI(&MBB, DL, get(MSP430::JCC)).addMBB(TBB).addImm(Cond[0].getImm());
27990593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  ++Count;
2808644af36903d933b6f9ae80d2d51b9e340c48452Anton Korobeynikov
28190593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  if (FBB) {
28290593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    // Two-way Conditional branch. Insert the second branch.
283c7f3ace20c325521c68335a1689645b43b06ddf0Chris Lattner    BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(FBB);
28490593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov    ++Count;
28590593d2e1f31fd1c3be353b836b50280c3a6d243Anton Korobeynikov  }
2868644af36903d933b6f9ae80d2d51b9e340c48452Anton Korobeynikov  return Count;
2878644af36903d933b6f9ae80d2d51b9e340c48452Anton Korobeynikov}
288702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov
289702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov/// GetInstSize - Return the number of bytes of code the specified
290702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov/// instruction may be.  This returns the maximum number of bytes.
291702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov///
292702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikovunsigned MSP430InstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
293e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &Desc = MI->getDesc();
294702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov
295702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov  switch (Desc.TSFlags & MSP430II::SizeMask) {
296702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov  default:
297702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov    switch (Desc.getOpcode()) {
298bc2198133a1836598b54b943420748e75d5dea94Craig Topper    default: llvm_unreachable("Unknown instruction size!");
2997431beaba2a01c3fe299c861b2ec85cbf1dc81c4Bill Wendling    case TargetOpcode::PROLOG_LABEL:
300518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner    case TargetOpcode::EH_LABEL:
301518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner    case TargetOpcode::IMPLICIT_DEF:
302518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner    case TargetOpcode::KILL:
303375be7730a6f3dee7a6dc319ee6c355a11ac99adDale Johannesen    case TargetOpcode::DBG_VALUE:
304702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov      return 0;
305518bb53485df640d7b7e3f6b0544099020c42aa7Chris Lattner    case TargetOpcode::INLINEASM: {
306702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov      const MachineFunction *MF = MI->getParent()->getParent();
307702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov      const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
308702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov      return TII.getInlineAsmLength(MI->getOperand(0).getSymbolName(),
309702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov                                    *MF->getTarget().getMCAsmInfo());
310702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov    }
311702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov    }
312702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov  case MSP430II::SizeSpecial:
313702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov    switch (MI->getOpcode()) {
314bc2198133a1836598b54b943420748e75d5dea94Craig Topper    default: llvm_unreachable("Unknown instruction size!");
315702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov    case MSP430::SAR8r1c:
316702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov    case MSP430::SAR16r1c:
317702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov      return 4;
318702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov    }
319702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov  case MSP430II::Size2Bytes:
320702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov    return 2;
321702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov  case MSP430II::Size4Bytes:
322702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov    return 4;
323702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov  case MSP430II::Size6Bytes:
324702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov    return 6;
325702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov  }
326702adaba6d7442f180c6bc0bec3a2b19e1169ed9Anton Korobeynikov}
327