27#include "llvm/IR/IntrinsicsMips.h"
33#define DEBUG_TYPE "mips-isel"
47void MipsSEDAGToDAGISel::addDSPCtrlRegOperands(
bool IsDef,
MachineInstr &
MI,
50 unsigned Mask =
MI.getOperand(1).getImm();
55 MIB.addReg(Mips::DSPPos, Flag);
58 MIB.addReg(Mips::DSPSCount, Flag);
61 MIB.addReg(Mips::DSPCarry, Flag);
64 MIB.addReg(Mips::DSPOutFlag, Flag);
67 MIB.addReg(Mips::DSPCCond, Flag);
70 MIB.addReg(Mips::DSPEFI, Flag);
75 return Mips::MSACtrlRegClass.getRegister(RegNum);
80 unsigned DstReg = 0, ZeroReg = 0;
83 if ((
MI.getOpcode() == Mips::ADDiu) &&
84 (
MI.getOperand(1).getReg() == Mips::ZERO) &&
85 (
MI.getOperand(2).isImm()) &&
86 (
MI.getOperand(2).getImm() == 0)) {
87 DstReg =
MI.getOperand(0).getReg();
89 }
else if ((
MI.getOpcode() == Mips::DADDiu) &&
90 (
MI.getOperand(1).getReg() == Mips::ZERO_64) &&
91 (
MI.getOperand(2).isImm()) &&
92 (
MI.getOperand(2).getImm() == 0)) {
93 DstReg =
MI.getOperand(0).getReg();
94 ZeroReg = Mips::ZERO_64;
102 E =
MRI->use_end(); U != E;) {
104 unsigned OpNo =
U.getOperandNo();
109 if (
MI->isPHI() ||
MI->isRegTiedToDefOperand(OpNo) ||
MI->isPseudo())
114 if (!
MRI->getRegClass(MO.
getReg())->contains(ZeroReg))
150void MipsSEDAGToDAGISel::processFunctionAfterISel(
MachineFunction &MF) {
155 for (
auto &
MBB:
MF) {
156 for (
auto &
MI:
MBB) {
157 switch (
MI.getOpcode()) {
159 addDSPCtrlRegOperands(
false,
MI,
MF);
162 addDSPCtrlRegOperands(
true,
MI,
MF);
164 case Mips::BuildPairF64_64:
165 case Mips::ExtractElementF64_64:
171 case Mips::BuildPairF64:
172 case Mips::ExtractElementF64:
178 if (
MI.getOperand(0).isGlobal() &&
179 MI.getOperand(0).getGlobal()->hasExternalLinkage() &&
180 MI.getOperand(0).getGlobal()->getName() ==
"_mcount")
183 case Mips::JALRPseudo:
184 case Mips::JALR64Pseudo:
185 case Mips::JALR16_MM:
186 if (
MI.getOperand(2).isMCSymbol() &&
187 MI.getOperand(2).getMCSymbol()->getName() ==
"_mcount")
191 if (
MI.getOperand(3).isMCSymbol() &&
192 MI.getOperand(3).getMCSymbol()->getName() ==
"_mcount")
196 replaceUsesWithZeroReg(
MRI,
MI);
206 EVT VT =
LHS.getValueType();
235 MVT::Glue, CstOne, InGlue);
238 Mips::EXT,
DL, MVT::i32,
SDValue(DSPCtrlField, 0), OuFlag, CstOne);
257 SDValue(DSPCtrlFinal, 0), CstOne);
267 EVT ValTy =
Addr.getValueType();
277bool MipsSEDAGToDAGISel::selectAddrFrameIndexOffset(
279 unsigned ShiftAmount = 0)
const {
281 auto *CN = cast<ConstantSDNode>(
Addr.getOperand(1));
282 if (
isIntN(OffsetBits + ShiftAmount, CN->getSExtValue())) {
283 EVT ValTy =
Addr.getValueType();
287 dyn_cast<FrameIndexSDNode>(
Addr.getOperand(0)))
293 const Align Alignment(1ULL << ShiftAmount);
294 if (!
isAligned(Alignment, CN->getZExtValue()))
344 if (isa<ConstantPoolSDNode>(Opnd0) || isa<GlobalAddressSDNode>(Opnd0) ||
345 isa<JumpTableSDNode>(Opnd0)) {
438 if (isa<FrameIndexSDNode>(
Base))
442 unsigned CnstOff = CN->getZExtValue();
443 return (CnstOff == (CnstOff & 0x3c));
507bool MipsSEDAGToDAGISel::selectVSplat(
SDNode *
N,
APInt &Imm,
508 unsigned MinSizeInBits)
const {
517 APInt SplatValue, SplatUndef;
518 unsigned SplatBitSize;
521 if (!
Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
546bool MipsSEDAGToDAGISel::
548 unsigned ImmBitSize)
const {
550 EVT EltTy =
N->getValueType(0).getVectorElementType();
553 N =
N->getOperand(0);
578bool MipsSEDAGToDAGISel::selectVSplatUimmPow2(
SDValue N,
SDValue &Imm)
const {
580 EVT EltTy =
N->getValueType(0).getVectorElementType();
583 N =
N->getOperand(0);
609bool MipsSEDAGToDAGISel::selectVSplatMaskL(
SDValue N,
SDValue &Imm)
const {
611 EVT EltTy =
N->getValueType(0).getVectorElementType();
614 N =
N->getOperand(0);
640bool MipsSEDAGToDAGISel::selectVSplatMaskR(
SDValue N,
SDValue &Imm)
const {
642 EVT EltTy =
N->getValueType(0).getVectorElementType();
645 N =
N->getOperand(0);
658bool MipsSEDAGToDAGISel::selectVSplatUimmInvPow2(
SDValue N,
661 EVT EltTy =
N->getValueType(0).getVectorElementType();
664 N =
N->getOperand(0);
668 int32_t
Log2 = (~ImmValue).exactLogBase2();
680bool MipsSEDAGToDAGISel::selectVSplatImmEq1(
SDValue N)
const {
682 EVT EltTy =
N->getValueType(0).getVectorElementType();
685 N =
N->getOperand(0);
687 return selectVSplat(
N.getNode(), ImmValue, EltTy.
getSizeInBits()) &&
691bool MipsSEDAGToDAGISel::trySelect(
SDNode *
Node) {
692 unsigned Opcode =
Node->getOpcode();
712 EVT NodeTys[] = {VT, VT};
714 ? Mips::PseudoD_SELECT_I64
715 : Mips::PseudoD_SELECT_I,
726 auto *CN = cast<ConstantFPSDNode>(
Node);
727 if (
Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) {
730 Mips::ZERO_64, MVT::i64);
735 Mips::ZERO, MVT::i32);
737 MVT::f64, Zero, Zero));
740 Mips::ZERO, MVT::i32);
742 MVT::f64, Zero, Zero));
750 auto *CN = cast<ConstantSDNode>(
Node);
751 int64_t
Imm = CN->getSExtValue();
752 unsigned Size = CN->getValueSizeInBits(0);
771 if (Inst->Opc == Mips::LUi64)
780 for (++Inst; Inst != Seq.
end(); ++Inst) {
792 const unsigned IntrinsicOpcode =
Node->getConstantOperandVal(1);
793 switch (IntrinsicOpcode) {
797 case Intrinsic::mips_cfcmsa: {
801 getMSACtrlReg(RegIdx), MVT::i32);
805 case Intrinsic::mips_ldr_d:
806 case Intrinsic::mips_ldr_w: {
807 unsigned Op = (IntrinsicOpcode == Intrinsic::mips_ldr_d) ? Mips::LDR_D
811 assert(
Node->getNumOperands() == 4 &&
"Unexpected number of operands.");
821 "Invalid instruction operand.");
825 cast<ConstantSDNode>(
Constant)->getConstantIntValue();
832 assert(
Node->getValueType(0).is128BitVector());
845 switch (
Node->getConstantOperandVal(0)) {
849 case Intrinsic::mips_move_v:
853 Node->getValueType(0),
854 Node->getOperand(1)));
861 const unsigned IntrinsicOpcode =
Node->getConstantOperandVal(1);
862 switch (IntrinsicOpcode) {
866 case Intrinsic::mips_ctcmsa: {
871 getMSACtrlReg(RegIdx),
Value);
875 case Intrinsic::mips_str_d:
876 case Intrinsic::mips_str_w: {
877 unsigned Op = (IntrinsicOpcode == Intrinsic::mips_str_d) ? Mips::STR_D
881 assert(
Node->getNumOperands() == 5 &&
"Unexpected number of operands.");
892 "Invalid instruction operand.");
896 cast<ConstantSDNode>(
Constant)->getConstantIntValue();
914 MVT ResTy =
Node->getSimpleValueType(0);
915 assert((ResTy == MVT::f64 || ResTy == MVT::f32) &&
916 "Unsupported float type!");
918 if (ResTy == MVT::f64)
926 Opc = Mips::FABS_D64_MM;
929 Opc = Mips::FABS_D32_MM;
932 Opc = Mips::FABS_S_MM;
954 if (
Node->getValueType(0) != MVT::i32 &&
Node->getValueType(0) != MVT::i64)
957 if (
Node->getNumOperands() != 4)
964 MVT ResTy =
Node->getSimpleValueType(0);
975 if (ResTy != MVT::i32 && ResTy != MVT::i64)
979 if (ResTy == MVT::i32) {
980 if (Pos +
Size <= 32)
983 if (Pos +
Size <= 32)
985 else if (Pos < 32 && 1 <
Size)
986 Opcode = Mips::DINSM;
988 Opcode = Mips::DINSU;
1005 unsigned RdhwrOpc, DestReg;
1007 if (PtrVT == MVT::i32) {
1008 RdhwrOpc = Mips::RDHWR;
1011 RdhwrOpc = Mips::RDHWR64;
1012 DestReg = Mips::V1_64;
1044 APInt SplatValue, SplatUndef;
1045 unsigned SplatBitSize;
1059 switch (SplatBitSize) {
1063 LdiOp = Mips::LDI_B;
1064 ViaVecTy = MVT::v16i8;
1067 LdiOp = Mips::LDI_H;
1068 ViaVecTy = MVT::v8i16;
1071 LdiOp = Mips::LDI_W;
1072 ViaVecTy = MVT::v4i32;
1075 LdiOp = Mips::LDI_D;
1076 ViaVecTy = MVT::v2i64;
1092 ((
ABI.IsO32() && SplatBitSize < 64) ||
1093 (
ABI.IsN32() ||
ABI.IsN64()))) {
1099 bool Is32BitSplat =
ABI.IsO32() || SplatBitSize < 64;
1100 const unsigned ADDiuOp = Is32BitSplat ? Mips::ADDiu : Mips::DADDiu;
1101 const MVT SplatMVT = Is32BitSplat ? MVT::i32 : MVT::i64;
1103 Is32BitSplat ? Mips::ZERO : Mips::ZERO_64, SplatMVT);
1105 const unsigned FILLOp =
1108 : (SplatBitSize == 32 ? Mips::FILL_W
1109 : (SplatBitSize == 64 ? Mips::FILL_D : 0));
1111 assert(FILLOp != 0 &&
"Unknown FILL Op for splat synthesis!");
1112 assert((!
ABI.IsO32() || (FILLOp != Mips::FILL_D)) &&
1113 "Attempting to use fill.d on MIPS32!");
1121 }
else if (SplatValue.
isSignedIntN(32) && SplatBitSize == 32) {
1138 assert((
Hi ||
Lo) &&
"Zero case reached 32 bit case splat synthesis!");
1142 }
else if (SplatValue.
isSignedIntN(32) && SplatBitSize == 64 &&
1143 (
ABI.IsN32() ||
ABI.IsN64())) {
1162 Mips::SUBREG_TO_REG,
DL, MVT::i64,
1236 Highest ?
SDValue(HiRes, 0) : ZeroVal,
1245 Mips::INSERT_W,
DL, MVT::v4i32,
SDValue(Res, 0),
1246 (Highest || Higher) ?
SDValue(HiRes, 0) : ZeroVal,
1254 Mips::COPY_TO_REGCLASS,
DL, ViaVecTy,
SDValue(Res, 0),
1258 Mips::SPLATI_D,
DL, MVT::v2i64,
SDValue(Res, 0),
1260 }
else if (
ABI.IsN64() ||
ABI.IsN32()) {
1264 const bool ResNonZero =
Hi ||
Lo;
1268 Mips::SUBREG_TO_REG,
DL, MVT::i64,
1275 Mips::SUBREG_TO_REG,
DL, MVT::i64,
1290 const ConstantInt *Const32 = ConstantInt::get(Int32Ty, 32);
1297 }
else if (HiResNonZero) {
1299 Mips::DSLL32,
DL, MVT::i64,
SDValue(HiRes, 0),
1303 "Zero splat value handled by non-zero 64bit splat synthesis!");
1313 if (ResVecTy != ViaVecTy) {
1336bool MipsSEDAGToDAGISel::SelectInlineAsmMemoryOperand(
1338 std::vector<SDValue> &OutOps) {
1341 switch(ConstraintID) {
1348 OutOps.push_back(
Base);
1349 OutOps.push_back(
Offset);
1352 OutOps.push_back(
Op);
1362 OutOps.push_back(
Base);
1363 OutOps.push_back(
Offset);
1366 OutOps.push_back(
Op);
1375 OutOps.push_back(
Base);
1376 OutOps.push_back(
Offset);
1382 OutOps.push_back(
Base);
1383 OutOps.push_back(
Offset);
1388 OutOps.push_back(
Base);
1389 OutOps.push_back(
Offset);
1393 OutOps.push_back(
Op);
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static uint64_t getConstant(const Value *IndexValue)
mir Rename Register Operands
Class for arbitrary precision integers.
LLVM_ABI APInt getLoBits(unsigned numBits) const
Compute an APInt containing numBits lowbits from this APInt.
uint64_t getZExtValue() const
Get zero extended value.
unsigned popcount() const
Count the number of bits set.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool isNegative() const
Determine sign of this APInt.
int32_t exactLogBase2() const
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
bool isShiftedMask() const
Return true if this APInt value contains a non-empty sequence of ones with the remainder zero.
bool isMask(unsigned numBits) const
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.
LLVM_ABI 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.
This is an important base class in LLVM.
This class represents an Operation in the Expression.
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 LLVM_ABI 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.
Wrapper class representing physical registers. Should be passed by value.
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.
LLVM_ABI 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
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...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
MipsSEDAGToDAGISelLegacy(MipsTargetMachine &TM, CodeGenOptLevel OL)
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.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
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
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
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.
const TargetLowering * getTargetLowering() const
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI 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),...
LLVM_ABI 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,...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
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.
@ 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,...
@ 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.
FunctionPass * createMipsSEISelDag(MipsTargetMachine &TM, CodeGenOptLevel OptLevel)
CodeGenOptLevel
Code generation optimization level.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
unsigned Log2(Align A)
Returns the log2 of the alignment.
Implement std::hash so that hash_code can be used in STL containers.
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.