Path: blob/main/contrib/llvm-project/llvm/lib/Target/MSP430/MSP430InstrInfo.cpp
35268 views
//===-- MSP430InstrInfo.cpp - MSP430 Instruction Information --------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file contains the MSP430 implementation of the TargetInstrInfo class.9//10//===----------------------------------------------------------------------===//1112#include "MSP430InstrInfo.h"13#include "MSP430.h"14#include "MSP430MachineFunctionInfo.h"15#include "MSP430TargetMachine.h"16#include "llvm/CodeGen/MachineFrameInfo.h"17#include "llvm/CodeGen/MachineInstrBuilder.h"18#include "llvm/CodeGen/MachineRegisterInfo.h"19#include "llvm/IR/Function.h"20#include "llvm/MC/TargetRegistry.h"21#include "llvm/Support/ErrorHandling.h"2223using namespace llvm;2425#define GET_INSTRINFO_CTOR_DTOR26#include "MSP430GenInstrInfo.inc"2728// Pin the vtable to this file.29void MSP430InstrInfo::anchor() {}3031MSP430InstrInfo::MSP430InstrInfo(MSP430Subtarget &STI)32: MSP430GenInstrInfo(MSP430::ADJCALLSTACKDOWN, MSP430::ADJCALLSTACKUP),33RI() {}3435void MSP430InstrInfo::storeRegToStackSlot(36MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg,37bool isKill, int FrameIdx, const TargetRegisterClass *RC,38const TargetRegisterInfo *TRI, Register VReg) const {39DebugLoc DL;40if (MI != MBB.end()) DL = MI->getDebugLoc();41MachineFunction &MF = *MBB.getParent();42MachineFrameInfo &MFI = MF.getFrameInfo();4344MachineMemOperand *MMO = MF.getMachineMemOperand(45MachinePointerInfo::getFixedStack(MF, FrameIdx),46MachineMemOperand::MOStore, MFI.getObjectSize(FrameIdx),47MFI.getObjectAlign(FrameIdx));4849if (RC == &MSP430::GR16RegClass)50BuildMI(MBB, MI, DL, get(MSP430::MOV16mr))51.addFrameIndex(FrameIdx).addImm(0)52.addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);53else if (RC == &MSP430::GR8RegClass)54BuildMI(MBB, MI, DL, get(MSP430::MOV8mr))55.addFrameIndex(FrameIdx).addImm(0)56.addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);57else58llvm_unreachable("Cannot store this register to stack slot!");59}6061void MSP430InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,62MachineBasicBlock::iterator MI,63Register DestReg, int FrameIdx,64const TargetRegisterClass *RC,65const TargetRegisterInfo *TRI,66Register VReg) const {67DebugLoc DL;68if (MI != MBB.end()) DL = MI->getDebugLoc();69MachineFunction &MF = *MBB.getParent();70MachineFrameInfo &MFI = MF.getFrameInfo();7172MachineMemOperand *MMO = MF.getMachineMemOperand(73MachinePointerInfo::getFixedStack(MF, FrameIdx),74MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIdx),75MFI.getObjectAlign(FrameIdx));7677if (RC == &MSP430::GR16RegClass)78BuildMI(MBB, MI, DL, get(MSP430::MOV16rm))79.addReg(DestReg, getDefRegState(true)).addFrameIndex(FrameIdx)80.addImm(0).addMemOperand(MMO);81else if (RC == &MSP430::GR8RegClass)82BuildMI(MBB, MI, DL, get(MSP430::MOV8rm))83.addReg(DestReg, getDefRegState(true)).addFrameIndex(FrameIdx)84.addImm(0).addMemOperand(MMO);85else86llvm_unreachable("Cannot store this register to stack slot!");87}8889void MSP430InstrInfo::copyPhysReg(MachineBasicBlock &MBB,90MachineBasicBlock::iterator I,91const DebugLoc &DL, MCRegister DestReg,92MCRegister SrcReg, bool KillSrc) const {93unsigned Opc;94if (MSP430::GR16RegClass.contains(DestReg, SrcReg))95Opc = MSP430::MOV16rr;96else if (MSP430::GR8RegClass.contains(DestReg, SrcReg))97Opc = MSP430::MOV8rr;98else99llvm_unreachable("Impossible reg-to-reg copy");100101BuildMI(MBB, I, DL, get(Opc), DestReg)102.addReg(SrcReg, getKillRegState(KillSrc));103}104105unsigned MSP430InstrInfo::removeBranch(MachineBasicBlock &MBB,106int *BytesRemoved) const {107assert(!BytesRemoved && "code size not handled");108109MachineBasicBlock::iterator I = MBB.end();110unsigned Count = 0;111112while (I != MBB.begin()) {113--I;114if (I->isDebugInstr())115continue;116if (I->getOpcode() != MSP430::JMP &&117I->getOpcode() != MSP430::JCC &&118I->getOpcode() != MSP430::Bi &&119I->getOpcode() != MSP430::Br &&120I->getOpcode() != MSP430::Bm)121break;122// Remove the branch.123I->eraseFromParent();124I = MBB.end();125++Count;126}127128return Count;129}130131bool MSP430InstrInfo::132reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {133assert(Cond.size() == 1 && "Invalid Xbranch condition!");134135MSP430CC::CondCodes CC = static_cast<MSP430CC::CondCodes>(Cond[0].getImm());136137switch (CC) {138default: llvm_unreachable("Invalid branch condition!");139case MSP430CC::COND_E:140CC = MSP430CC::COND_NE;141break;142case MSP430CC::COND_NE:143CC = MSP430CC::COND_E;144break;145case MSP430CC::COND_L:146CC = MSP430CC::COND_GE;147break;148case MSP430CC::COND_GE:149CC = MSP430CC::COND_L;150break;151case MSP430CC::COND_HS:152CC = MSP430CC::COND_LO;153break;154case MSP430CC::COND_LO:155CC = MSP430CC::COND_HS;156break;157}158159Cond[0].setImm(CC);160return false;161}162163bool MSP430InstrInfo::analyzeBranch(MachineBasicBlock &MBB,164MachineBasicBlock *&TBB,165MachineBasicBlock *&FBB,166SmallVectorImpl<MachineOperand> &Cond,167bool AllowModify) const {168// Start from the bottom of the block and work up, examining the169// terminator instructions.170MachineBasicBlock::iterator I = MBB.end();171while (I != MBB.begin()) {172--I;173if (I->isDebugInstr())174continue;175176// Working from the bottom, when we see a non-terminator177// instruction, we're done.178if (!isUnpredicatedTerminator(*I))179break;180181// A terminator that isn't a branch can't easily be handled182// by this analysis.183if (!I->isBranch())184return true;185186// Cannot handle indirect branches.187if (I->getOpcode() == MSP430::Br ||188I->getOpcode() == MSP430::Bm)189return true;190191// Handle unconditional branches.192if (I->getOpcode() == MSP430::JMP || I->getOpcode() == MSP430::Bi) {193if (!AllowModify) {194TBB = I->getOperand(0).getMBB();195continue;196}197198// If the block has any instructions after a JMP, delete them.199MBB.erase(std::next(I), MBB.end());200Cond.clear();201FBB = nullptr;202203// Delete the JMP if it's equivalent to a fall-through.204if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {205TBB = nullptr;206I->eraseFromParent();207I = MBB.end();208continue;209}210211// TBB is used to indicate the unconditinal destination.212TBB = I->getOperand(0).getMBB();213continue;214}215216// Handle conditional branches.217assert(I->getOpcode() == MSP430::JCC && "Invalid conditional branch");218MSP430CC::CondCodes BranchCode =219static_cast<MSP430CC::CondCodes>(I->getOperand(1).getImm());220if (BranchCode == MSP430CC::COND_INVALID)221return true; // Can't handle weird stuff.222223// Working from the bottom, handle the first conditional branch.224if (Cond.empty()) {225FBB = TBB;226TBB = I->getOperand(0).getMBB();227Cond.push_back(MachineOperand::CreateImm(BranchCode));228continue;229}230231// Handle subsequent conditional branches. Only handle the case where all232// conditional branches branch to the same destination.233assert(Cond.size() == 1);234assert(TBB);235236// Only handle the case where all conditional branches branch to237// the same destination.238if (TBB != I->getOperand(0).getMBB())239return true;240241MSP430CC::CondCodes OldBranchCode = (MSP430CC::CondCodes)Cond[0].getImm();242// If the conditions are the same, we can leave them alone.243if (OldBranchCode == BranchCode)244continue;245246return true;247}248249return false;250}251252unsigned MSP430InstrInfo::insertBranch(MachineBasicBlock &MBB,253MachineBasicBlock *TBB,254MachineBasicBlock *FBB,255ArrayRef<MachineOperand> Cond,256const DebugLoc &DL,257int *BytesAdded) const {258// Shouldn't be a fall through.259assert(TBB && "insertBranch must not be told to insert a fallthrough");260assert((Cond.size() == 1 || Cond.size() == 0) &&261"MSP430 branch conditions have one component!");262assert(!BytesAdded && "code size not handled");263264if (Cond.empty()) {265// Unconditional branch?266assert(!FBB && "Unconditional branch with multiple successors!");267BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(TBB);268return 1;269}270271// Conditional branch.272unsigned Count = 0;273BuildMI(&MBB, DL, get(MSP430::JCC)).addMBB(TBB).addImm(Cond[0].getImm());274++Count;275276if (FBB) {277// Two-way Conditional branch. Insert the second branch.278BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(FBB);279++Count;280}281return Count;282}283284/// GetInstSize - Return the number of bytes of code the specified285/// instruction may be. This returns the maximum number of bytes.286///287unsigned MSP430InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {288const MCInstrDesc &Desc = MI.getDesc();289290switch (Desc.getOpcode()) {291case TargetOpcode::CFI_INSTRUCTION:292case TargetOpcode::EH_LABEL:293case TargetOpcode::IMPLICIT_DEF:294case TargetOpcode::KILL:295case TargetOpcode::DBG_VALUE:296return 0;297case TargetOpcode::INLINEASM:298case TargetOpcode::INLINEASM_BR: {299const MachineFunction *MF = MI.getParent()->getParent();300const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();301return TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(),302*MF->getTarget().getMCAsmInfo());303}304}305306return Desc.getSize();307}308309310