//===-- XCoreInstrInfo.cpp - XCore Instruction Information ----------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file contains the XCore implementation of the TargetInstrInfo class. // //===----------------------------------------------------------------------===// #include "XCoreInstrInfo.h" #include "XCore.h" #include "XCoreMachineFunctionInfo.h" #include "llvm/ADT/STLExtras.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/TargetRegistry.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" usingnamespacellvm; #define GET_INSTRINFO_CTOR_DTOR #include "XCoreGenInstrInfo.inc" namespace llvm { namespace XCore { // XCore Condition Codes enum CondCode { … }; } } // Pin the vtable to this file. void XCoreInstrInfo::anchor() { … } XCoreInstrInfo::XCoreInstrInfo() : … { … } static bool isZeroImm(const MachineOperand &op) { … } /// isLoadFromStackSlot - If the specified machine instruction is a direct /// load from a stack slot, return the virtual or physical register number of /// the destination along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than loading from the stack slot. Register XCoreInstrInfo::isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const { … } /// isStoreToStackSlot - If the specified machine instruction is a direct /// store to a stack slot, return the virtual or physical register number of /// the source reg along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than storing to the stack slot. Register XCoreInstrInfo::isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const { … } //===----------------------------------------------------------------------===// // Branch Analysis //===----------------------------------------------------------------------===// static inline bool IsBRU(unsigned BrOpc) { … } static inline bool IsBRT(unsigned BrOpc) { … } static inline bool IsBRF(unsigned BrOpc) { … } static inline bool IsCondBranch(unsigned BrOpc) { … } static inline bool IsBR_JT(unsigned BrOpc) { … } /// GetCondFromBranchOpc - Return the XCore CC that matches /// the correspondent Branch instruction opcode. static XCore::CondCode GetCondFromBranchOpc(unsigned BrOpc) { … } /// GetCondBranchFromCond - Return the Branch instruction /// opcode that matches the cc. static inline unsigned GetCondBranchFromCond(XCore::CondCode CC) { … } /// GetOppositeBranchCondition - Return the inverse of the specified /// condition, e.g. turning COND_E to COND_NE. static inline XCore::CondCode GetOppositeBranchCondition(XCore::CondCode CC) { … } /// analyzeBranch - Analyze the branching code at the end of MBB, returning /// true if it cannot be understood (e.g. it's a switch dispatch or isn't /// implemented for a target). Upon success, this returns false and returns /// with the following information in various cases: /// /// 1. If this block ends with no branches (it just falls through to its succ) /// just return false, leaving TBB/FBB null. /// 2. If this block ends with only an unconditional branch, it sets TBB to be /// the destination block. /// 3. If this block ends with an conditional branch and it falls through to /// an successor block, it sets TBB to be the branch destination block and a /// list of operands that evaluate the condition. These /// operands can be passed to other TargetInstrInfo methods to create new /// branches. /// 4. If this block ends with an conditional branch and an unconditional /// block, it returns the 'true' destination in TBB, the 'false' destination /// in FBB, and a list of operands that evaluate the condition. These /// operands can be passed to other TargetInstrInfo methods to create new /// branches. /// /// Note that removeBranch and insertBranch must be implemented to support /// cases where this method returns success. /// bool XCoreInstrInfo::analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl<MachineOperand> &Cond, bool AllowModify) const { … } unsigned XCoreInstrInfo::insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const { … } unsigned XCoreInstrInfo::removeBranch(MachineBasicBlock &MBB, int *BytesRemoved) const { … } void XCoreInstrInfo::copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc, bool RenamableDest, bool RenamableSrc) const { … } void XCoreInstrInfo::storeRegToStackSlot( MachineBasicBlock &MBB, MachineBasicBlock::iterator I, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const { … } void XCoreInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const { … } bool XCoreInstrInfo:: reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { … } static inline bool isImmU6(unsigned val) { … } static inline bool isImmU16(unsigned val) { … } static bool isImmMskBitp(unsigned val) { … } MachineBasicBlock::iterator XCoreInstrInfo::loadImmediate( MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned Reg, uint64_t Value) const { … }