blob: cd8b6d5fba59cae5b729e456a5b7aed41a869603 [file] [log] [blame]
//===-- RISCVInstrInfo.h - RISCV Instruction Information --------*- C++ -*-===//
//
// 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 RISCV implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_RISCV_RISCVINSTRINFO_H
#define LLVM_LIB_TARGET_RISCV_RISCVINSTRINFO_H
#include "RISCVRegisterInfo.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#define GET_INSTRINFO_HEADER
#include "RISCVGenInstrInfo.inc"
namespace llvm {
class RISCVSubtarget;
class RISCVInstrInfo : public RISCVGenInstrInfo {
public:
explicit RISCVInstrInfo(RISCVSubtarget &STI);
unsigned isLoadFromStackSlot(const MachineInstr &MI,
int &FrameIndex) const override;
unsigned isStoreToStackSlot(const MachineInstr &MI,
int &FrameIndex) const override;
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg,
bool KillSrc) const override;
void storeRegToStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI, Register SrcReg,
bool IsKill, int FrameIndex,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const override;
void loadRegFromStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI, Register DstReg,
int FrameIndex, const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const override;
// Materializes the given integer Val into DstReg.
void movImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
const DebugLoc &DL, Register DstReg, uint64_t Val,
MachineInstr::MIFlag Flag = MachineInstr::NoFlags) const;
unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify) const override;
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
const DebugLoc &dl,
int *BytesAdded = nullptr) const override;
unsigned insertIndirectBranch(MachineBasicBlock &MBB,
MachineBasicBlock &NewDestBB,
const DebugLoc &DL, int64_t BrOffset,
RegScavenger *RS = nullptr) const override;
unsigned removeBranch(MachineBasicBlock &MBB,
int *BytesRemoved = nullptr) const override;
bool
reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
bool isBranchOffsetInRange(unsigned BranchOpc,
int64_t BrOffset) const override;
bool isAsCheapAsAMove(const MachineInstr &MI) const override;
bool verifyInstruction(const MachineInstr &MI,
StringRef &ErrInfo) const override;
bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt,
const MachineOperand *&BaseOp,
int64_t &Offset, unsigned &Width,
const TargetRegisterInfo *TRI) const;
bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa,
const MachineInstr &MIb) const override;
std::pair<unsigned, unsigned>
decomposeMachineOperandsTargetFlags(unsigned TF) const override;
ArrayRef<std::pair<unsigned, const char *>>
getSerializableDirectMachineOperandTargetFlags() const override;
// Return true if the function can safely be outlined from.
virtual bool
isFunctionSafeToOutlineFrom(MachineFunction &MF,
bool OutlineFromLinkOnceODRs) const override;
// Return true if MBB is safe to outline from, and return any target-specific
// information in Flags.
virtual bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB,
unsigned &Flags) const override;
// Calculate target-specific information for a set of outlining candidates.
outliner::OutlinedFunction getOutliningCandidateInfo(
std::vector<outliner::Candidate> &RepeatedSequenceLocs) const override;
// Return if/how a given MachineInstr should be outlined.
virtual outliner::InstrType
getOutliningType(MachineBasicBlock::iterator &MBBI,
unsigned Flags) const override;
// Insert a custom frame for outlined functions.
virtual void
buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF,
const outliner::OutlinedFunction &OF) const override;
// Insert a call to an outlined function into a given basic block.
virtual MachineBasicBlock::iterator
insertOutlinedCall(Module &M, MachineBasicBlock &MBB,
MachineBasicBlock::iterator &It, MachineFunction &MF,
const outliner::Candidate &C) const override;
protected:
const RISCVSubtarget &STI;
};
namespace RISCV {
// Match with the definitions in RISCVInstrFormatsV.td
enum RVVConstraintType {
NoConstraint = 0,
VS2Constraint = 0b0001,
VS1Constraint = 0b0010,
VMConstraint = 0b0100,
OneInput = 0b1000,
// Illegal instructions:
//
// * The destination vector register group for a masked vector instruction
// cannot overlap the source mask register (v0), unless the destination vector
// register is being written with a mask value (e.g., comparisons) or the
// scalar result of a reduction.
//
// * Widening: The destination vector register group cannot overlap a source
// vector register group of a different EEW
//
// * Narrowing: The destination vector register group cannot overlap the
// first source vector register group
//
// * For vadc and vsbc, an illegal instruction exception is raised if the
// destination vector register is v0.
//
// * For vmadc and vmsbc, an illegal instruction exception is raised if the
// destination vector register overlaps a source vector register group.
//
// * viota: An illegal instruction exception is raised if the destination
// vector register group overlaps the source vector mask register. If the
// instruction is masked, an illegal instruction exception is issued if the
// destination vector register group overlaps v0.
//
// * v[f]slide[1]up: The destination vector register group for vslideup cannot
// overlap the source vector register group.
//
// * vrgather: The destination vector register group cannot overlap with the
// source vector register groups.
//
// * vcompress: The destination vector register group cannot overlap the
// source vector register group or the source mask register
WidenV = VS2Constraint | VS1Constraint | VMConstraint,
WidenW = VS1Constraint | VMConstraint,
WidenCvt = VS2Constraint | VMConstraint | OneInput,
Narrow = VS2Constraint | VMConstraint,
NarrowCvt = VS2Constraint | VMConstraint | OneInput,
Vmadc = VS2Constraint | VS1Constraint,
Iota = VS2Constraint | VMConstraint | OneInput,
SlideUp = VS2Constraint | VMConstraint,
Vrgather = VS2Constraint | VS1Constraint | VMConstraint,
Vcompress = VS2Constraint | VS1Constraint,
ConstraintOffset = 5,
ConstraintMask = 0b1111
};
} // end namespace RISCV
} // end namespace llvm
#endif