30#include "llvm/IR/IntrinsicsMips.h"
38#define DEBUG_TYPE "mips-isel"
47void MipsSEDAGToDAGISel::getAnalysisUsage(
AnalysisUsage &AU)
const {
52void MipsSEDAGToDAGISel::addDSPCtrlRegOperands(
bool IsDef,
MachineInstr &
MI,
55 unsigned Mask =
MI.getOperand(1).getImm();
60 MIB.addReg(Mips::DSPPos, Flag);
63 MIB.addReg(Mips::DSPSCount, Flag);
66 MIB.addReg(Mips::DSPCarry, Flag);
69 MIB.addReg(Mips::DSPOutFlag, Flag);
72 MIB.addReg(Mips::DSPCCond, Flag);
75 MIB.addReg(Mips::DSPEFI, Flag);
78unsigned MipsSEDAGToDAGISel::getMSACtrlReg(
const SDValue RegIdx)
const {
79 uint64_t RegNum = cast<ConstantSDNode>(RegIdx)->getZExtValue();
80 return Mips::MSACtrlRegClass.getRegister(RegNum);
85 unsigned DstReg = 0, ZeroReg = 0;
88 if ((
MI.getOpcode() == Mips::ADDiu) &&
89 (
MI.getOperand(1).getReg() == Mips::ZERO) &&
90 (
MI.getOperand(2).isImm()) &&
91 (
MI.getOperand(2).getImm() == 0)) {
92 DstReg =
MI.getOperand(0).getReg();
94 }
else if ((
MI.getOpcode() == Mips::DADDiu) &&
95 (
MI.getOperand(1).getReg() == Mips::ZERO_64) &&
96 (
MI.getOperand(2).isImm()) &&
97 (
MI.getOperand(2).getImm() == 0)) {
98 DstReg =
MI.getOperand(0).getReg();
99 ZeroReg = Mips::ZERO_64;
107 E =
MRI->use_end(); U !=
E;) {
109 unsigned OpNo = U.getOperandNo();
114 if (
MI->isPHI() ||
MI->isRegTiedToDefOperand(OpNo) ||
MI->isPseudo())
119 if (!
MRI->getRegClass(MO.
getReg())->contains(ZeroReg))
155void MipsSEDAGToDAGISel::processFunctionAfterISel(
MachineFunction &MF) {
160 for (
auto &
MBB:
MF) {
161 for (
auto &
MI:
MBB) {
162 switch (
MI.getOpcode()) {
164 addDSPCtrlRegOperands(
false,
MI,
MF);
167 addDSPCtrlRegOperands(
true,
MI,
MF);
169 case Mips::BuildPairF64_64:
170 case Mips::ExtractElementF64_64:
176 case Mips::BuildPairF64:
177 case Mips::ExtractElementF64:
183 if (
MI.getOperand(0).isGlobal() &&
184 MI.getOperand(0).getGlobal()->getGlobalIdentifier() ==
"_mcount")
187 case Mips::JALRPseudo:
188 case Mips::JALR64Pseudo:
189 case Mips::JALR16_MM:
190 if (
MI.getOperand(2).isMCSymbol() &&
191 MI.getOperand(2).getMCSymbol()->getName() ==
"_mcount")
195 if (
MI.getOperand(3).isMCSymbol() &&
196 MI.getOperand(3).getMCSymbol()->getName() ==
"_mcount")
200 replaceUsesWithZeroReg(
MRI,
MI);
210 EVT VT =
LHS.getValueType();
261 SDValue(DSPCtrlFinal, 0), CstOne);
271 EVT ValTy =
Addr.getValueType();
281bool MipsSEDAGToDAGISel::selectAddrFrameIndexOffset(
283 unsigned ShiftAmount = 0)
const {
285 auto *CN = cast<ConstantSDNode>(
Addr.getOperand(1));
286 if (
isIntN(OffsetBits + ShiftAmount, CN->getSExtValue())) {
287 EVT ValTy =
Addr.getValueType();
291 dyn_cast<FrameIndexSDNode>(
Addr.getOperand(0)))
297 const Align Alignment(1ULL << ShiftAmount);
298 if (!
isAligned(Alignment, CN->getZExtValue()))
348 if (isa<ConstantPoolSDNode>(Opnd0) || isa<GlobalAddressSDNode>(Opnd0) ||
349 isa<JumpTableSDNode>(Opnd0)) {
442 if (isa<FrameIndexSDNode>(
Base))
446 unsigned CnstOff = CN->getZExtValue();
447 return (CnstOff == (CnstOff & 0x3c));
511bool MipsSEDAGToDAGISel::selectVSplat(
SDNode *
N,
APInt &Imm,
512 unsigned MinSizeInBits)
const {
521 APInt SplatValue, SplatUndef;
522 unsigned SplatBitSize;
525 if (!
Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
550bool MipsSEDAGToDAGISel::
552 unsigned ImmBitSize)
const {
554 EVT EltTy =
N->getValueType(0).getVectorElementType();
557 N =
N->getOperand(0);
573bool MipsSEDAGToDAGISel::
575 return selectVSplatCommon(
N, Imm,
false, 1);
578bool MipsSEDAGToDAGISel::
580 return selectVSplatCommon(
N, Imm,
false, 2);
583bool MipsSEDAGToDAGISel::
585 return selectVSplatCommon(
N, Imm,
false, 3);
589bool MipsSEDAGToDAGISel::
591 return selectVSplatCommon(
N, Imm,
false, 4);
595bool MipsSEDAGToDAGISel::
597 return selectVSplatCommon(
N, Imm,
false, 5);
601bool MipsSEDAGToDAGISel::
603 return selectVSplatCommon(
N, Imm,
false, 6);
607bool MipsSEDAGToDAGISel::
609 return selectVSplatCommon(
N, Imm,
false, 8);
613bool MipsSEDAGToDAGISel::
615 return selectVSplatCommon(
N, Imm,
true, 5);
628bool MipsSEDAGToDAGISel::selectVSplatUimmPow2(
SDValue N,
SDValue &Imm)
const {
630 EVT EltTy =
N->getValueType(0).getVectorElementType();
633 N =
N->getOperand(0);
659bool MipsSEDAGToDAGISel::selectVSplatMaskL(
SDValue N,
SDValue &Imm)
const {
661 EVT EltTy =
N->getValueType(0).getVectorElementType();
664 N =
N->getOperand(0);
671 if (ImmValue == ~(~ImmValue & ~(~ImmValue + 1))) {
693bool MipsSEDAGToDAGISel::selectVSplatMaskR(
SDValue N,
SDValue &Imm)
const {
695 EVT EltTy =
N->getValueType(0).getVectorElementType();
698 N =
N->getOperand(0);
704 if (ImmValue == (ImmValue & ~(ImmValue + 1))) {
714bool MipsSEDAGToDAGISel::selectVSplatUimmInvPow2(
SDValue N,
717 EVT EltTy =
N->getValueType(0).getVectorElementType();
720 N =
N->getOperand(0);
724 int32_t
Log2 = (~ImmValue).exactLogBase2();
735bool MipsSEDAGToDAGISel::trySelect(
SDNode *
Node) {
736 unsigned Opcode =
Node->getOpcode();
746 case Mips::PseudoD_SELECT_I:
747 case Mips::PseudoD_SELECT_I64: {
756 EVT NodeTys[] = {VT, VT};
758 ? Mips::PseudoD_SELECT_I64
759 : Mips::PseudoD_SELECT_I,
770 auto *CN = cast<ConstantFPSDNode>(
Node);
771 if (
Node->getValueType(0) ==
MVT::f64 && CN->isExactlyValue(+0.0)) {
794 auto *CN = cast<ConstantSDNode>(
Node);
795 int64_t
Imm = CN->getSExtValue();
796 unsigned Size = CN->getValueSizeInBits(0);
815 if (Inst->Opc == Mips::LUi64)
824 for (++Inst; Inst != Seq.
end(); ++Inst) {
836 const unsigned IntrinsicOpcode =
837 cast<ConstantSDNode>(
Node->getOperand(1))->getZExtValue();
838 switch (IntrinsicOpcode) {
842 case Intrinsic::mips_cfcmsa: {
850 case Intrinsic::mips_ldr_d:
851 case Intrinsic::mips_ldr_w: {
852 unsigned Op = (IntrinsicOpcode == Intrinsic::mips_ldr_d) ? Mips::LDR_D
856 assert(
Node->getNumOperands() == 4 &&
"Unexpected number of operands.");
866 "Invalid instruction operand.");
870 cast<ConstantSDNode>(
Constant)->getConstantIntValue();
877 assert(
Node->getValueType(0).is128BitVector());
890 switch (cast<ConstantSDNode>(
Node->getOperand(0))->getZExtValue()) {
894 case Intrinsic::mips_move_v:
898 Node->getValueType(0),
899 Node->getOperand(1)));
906 const unsigned IntrinsicOpcode =
907 cast<ConstantSDNode>(
Node->getOperand(1))->getZExtValue();
908 switch (IntrinsicOpcode) {
912 case Intrinsic::mips_ctcmsa: {
917 getMSACtrlReg(RegIdx),
Value);
921 case Intrinsic::mips_str_d:
922 case Intrinsic::mips_str_w: {
923 unsigned Op = (IntrinsicOpcode == Intrinsic::mips_str_d) ? Mips::STR_D
927 assert(
Node->getNumOperands() == 5 &&
"Unexpected number of operands.");
938 "Invalid instruction operand.");
942 cast<ConstantSDNode>(
Constant)->getConstantIntValue();
960 MVT ResTy =
Node->getSimpleValueType(0);
962 "Unsupported float type!");
972 Opc = Mips::FABS_D64_MM;
975 Opc = Mips::FABS_D32_MM;
978 Opc = Mips::FABS_S_MM;
1003 if (
Node->getNumOperands() != 4)
1010 MVT ResTy =
Node->getSimpleValueType(0);
1018 if (Pos +
Size > 64)
1024 unsigned Opcode = 0;
1026 if (Pos +
Size <= 32)
1029 if (Pos +
Size <= 32)
1030 Opcode = Mips::DINS;
1031 else if (Pos < 32 && 1 <
Size)
1032 Opcode = Mips::DINSM;
1034 Opcode = Mips::DINSU;
1051 unsigned RdhwrOpc, DestReg;
1054 RdhwrOpc = Mips::RDHWR;
1057 RdhwrOpc = Mips::RDHWR64;
1058 DestReg = Mips::V1_64;
1090 APInt SplatValue, SplatUndef;
1091 unsigned SplatBitSize;
1105 switch (SplatBitSize) {
1109 LdiOp = Mips::LDI_B;
1113 LdiOp = Mips::LDI_H;
1117 LdiOp = Mips::LDI_W;
1121 LdiOp = Mips::LDI_D;
1138 ((
ABI.IsO32() && SplatBitSize < 64) ||
1139 (
ABI.IsN32() ||
ABI.IsN64()))) {
1145 bool Is32BitSplat =
ABI.IsO32() || SplatBitSize < 64;
1146 const unsigned ADDiuOp = Is32BitSplat ? Mips::ADDiu : Mips::DADDiu;
1149 Is32BitSplat ? Mips::ZERO : Mips::ZERO_64, SplatMVT);
1151 const unsigned FILLOp =
1154 : (SplatBitSize == 32 ? Mips::FILL_W
1155 : (SplatBitSize == 64 ? Mips::FILL_D : 0));
1157 assert(FILLOp != 0 &&
"Unknown FILL Op for splat synthesis!");
1158 assert((!
ABI.IsO32() || (FILLOp != Mips::FILL_D)) &&
1159 "Attempting to use fill.d on MIPS32!");
1167 }
else if (SplatValue.
isSignedIntN(32) && SplatBitSize == 32) {
1184 assert((
Hi ||
Lo) &&
"Zero case reached 32 bit case splat synthesis!");
1188 }
else if (SplatValue.
isSignedIntN(32) && SplatBitSize == 64 &&
1189 (
ABI.IsN32() ||
ABI.IsN64())) {
1282 Highest ?
SDValue(HiRes, 0) : ZeroVal,
1292 (Highest || Higher) ?
SDValue(HiRes, 0) : ZeroVal,
1300 Mips::COPY_TO_REGCLASS,
DL, ViaVecTy,
SDValue(Res, 0),
1306 }
else if (
ABI.IsN64() ||
ABI.IsN32()) {
1310 const bool ResNonZero =
Hi ||
Lo;
1343 }
else if (HiResNonZero) {
1349 "Zero splat value handled by non-zero 64bit splat synthesis!");
1359 if (ResVecTy != ViaVecTy) {
1382bool MipsSEDAGToDAGISel::
1383SelectInlineAsmMemoryOperand(
const SDValue &Op,
unsigned ConstraintID,
1384 std::vector<SDValue> &OutOps) {
1387 switch(ConstraintID) {
1394 OutOps.push_back(
Base);
1395 OutOps.push_back(
Offset);
1398 OutOps.push_back(Op);
1408 OutOps.push_back(
Base);
1409 OutOps.push_back(
Offset);
1412 OutOps.push_back(Op);
1421 OutOps.push_back(
Base);
1422 OutOps.push_back(
Offset);
1428 OutOps.push_back(
Base);
1429 OutOps.push_back(
Offset);
1432 }
else if (selectAddrRegImm16(Op,
Base,
Offset)) {
1434 OutOps.push_back(
Base);
1435 OutOps.push_back(
Offset);
1439 OutOps.push_back(Op);
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
mir Rename Register Operands
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Class for arbitrary precision integers.
APInt getLoBits(unsigned numBits) const
Compute an APInt containing numBits lowbits from this APInt.
uint64_t getZExtValue() const
Get zero extended value.
unsigned getBitWidth() const
Return the number of bits in the APInt.
int32_t exactLogBase2() const
unsigned countPopulation() const
Count the number of bits set.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
bool isIntN(unsigned N) const
Check if this APInt has an N-bits unsigned integer value.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
A "pseudo-class" with methods for operating on BUILD_VECTORs.
bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
This is the shared class of boolean and integer constants.
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
This is an important base class in LLVM.
Legacy analysis pass which computes a DominatorTree.
FunctionPass class - This class is used to implement most global optimizations.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Class to represent integer types.
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
void setReg(Register Reg)
Change the register this operand corresponds to.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
reg_begin/reg_end - Provide iteration support to walk over all definitions and uses of a register wit...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const MipsSubtarget * Subtarget
Keep a pointer to the MipsSubtarget around so that we can make the right decision when generating cod...
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
bool inMicroMipsMode() const
bool inMips16Mode() const
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
unsigned getOpcode() const
CodeGenOpt::Level OptLevel
const TargetLowering * TLI
const TargetInstrInfo * TII
void ReplaceNode(SDNode *F, SDNode *T)
Replace all uses of F with T, then remove F from the DAG.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetLowering * getTargetLowering() const
MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
SDNode * SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT)
These are used for target selectors to mutate the specified node to have the specified return type,...
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
SDValue getRegister(unsigned Reg, EVT VT)
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
bool isPositionIndependent() const
unsigned getID() const
Return the register class ID number.
LLVM Value Representation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Level
Code generation optimization level.
@ ADDC
Carry-setting nodes for multiple precision addition and subtraction.
@ ADD
Simple integer binary arithmetic operators.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ TargetConstant
TargetConstant* - Like Constant*, but the DAG does not do any folding, simplification,...
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ ADDE
Carry-using nodes for multiple precision addition and subtraction.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Flag
These should be considered private to the implementation of the MCInstrDesc class.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Undef
Value of the register doesn't matter.
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
FunctionPass * createMipsSEISelDag(MipsTargetMachine &TM, CodeGenOpt::Level OptLevel)
unsigned Log2(Align A)
Returns the log2 of the alignment.
This struct is a compact representation of a valid (non-zero power of two) alignment.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
EVT getVectorElementType() const
Given a vector type, return the type of each element.