30#include "llvm/IR/IntrinsicsMips.h"
38#define DEBUG_TYPE "mips-isel"
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 {
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();
239 MVT::Glue, CstOne, InGlue);
242 Mips::EXT,
DL, MVT::i32,
SDValue(DSPCtrlField, 0), OuFlag, CstOne);
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))) {
692bool MipsSEDAGToDAGISel::selectVSplatMaskR(
SDValue N,
SDValue &Imm)
const {
694 EVT EltTy =
N->getValueType(0).getVectorElementType();
697 N =
N->getOperand(0);
703 if (ImmValue == (ImmValue & ~(ImmValue + 1))) {
712bool MipsSEDAGToDAGISel::selectVSplatUimmInvPow2(
SDValue N,
715 EVT EltTy =
N->getValueType(0).getVectorElementType();
718 N =
N->getOperand(0);
722 int32_t
Log2 = (~ImmValue).exactLogBase2();
733bool MipsSEDAGToDAGISel::trySelect(
SDNode *
Node) {
734 unsigned Opcode =
Node->getOpcode();
754 EVT NodeTys[] = {VT, VT};
756 ? Mips::PseudoD_SELECT_I64
757 : Mips::PseudoD_SELECT_I,
768 auto *CN = cast<ConstantFPSDNode>(
Node);
769 if (
Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) {
772 Mips::ZERO_64, MVT::i64);
777 Mips::ZERO, MVT::i32);
779 MVT::f64, Zero, Zero));
782 Mips::ZERO, MVT::i32);
784 MVT::f64, Zero, Zero));
792 auto *CN = cast<ConstantSDNode>(
Node);
793 int64_t
Imm = CN->getSExtValue();
794 unsigned Size = CN->getValueSizeInBits(0);
813 if (Inst->Opc == Mips::LUi64)
822 for (++Inst; Inst != Seq.
end(); ++Inst) {
834 const unsigned IntrinsicOpcode =
Node->getConstantOperandVal(1);
835 switch (IntrinsicOpcode) {
839 case Intrinsic::mips_cfcmsa: {
843 getMSACtrlReg(RegIdx), MVT::i32);
847 case Intrinsic::mips_ldr_d:
848 case Intrinsic::mips_ldr_w: {
849 unsigned Op = (IntrinsicOpcode == Intrinsic::mips_ldr_d) ? Mips::LDR_D
853 assert(
Node->getNumOperands() == 4 &&
"Unexpected number of operands.");
863 "Invalid instruction operand.");
867 cast<ConstantSDNode>(
Constant)->getConstantIntValue();
874 assert(
Node->getValueType(0).is128BitVector());
887 switch (
Node->getConstantOperandVal(0)) {
891 case Intrinsic::mips_move_v:
895 Node->getValueType(0),
896 Node->getOperand(1)));
903 const unsigned IntrinsicOpcode =
Node->getConstantOperandVal(1);
904 switch (IntrinsicOpcode) {
908 case Intrinsic::mips_ctcmsa: {
913 getMSACtrlReg(RegIdx),
Value);
917 case Intrinsic::mips_str_d:
918 case Intrinsic::mips_str_w: {
919 unsigned Op = (IntrinsicOpcode == Intrinsic::mips_str_d) ? Mips::STR_D
923 assert(
Node->getNumOperands() == 5 &&
"Unexpected number of operands.");
934 "Invalid instruction operand.");
938 cast<ConstantSDNode>(
Constant)->getConstantIntValue();
956 MVT ResTy =
Node->getSimpleValueType(0);
957 assert((ResTy == MVT::f64 || ResTy == MVT::f32) &&
958 "Unsupported float type!");
960 if (ResTy == MVT::f64)
968 Opc = Mips::FABS_D64_MM;
971 Opc = Mips::FABS_D32_MM;
974 Opc = Mips::FABS_S_MM;
996 if (
Node->getValueType(0) != MVT::i32 &&
Node->getValueType(0) != MVT::i64)
999 if (
Node->getNumOperands() != 4)
1006 MVT ResTy =
Node->getSimpleValueType(0);
1014 if (Pos +
Size > 64)
1017 if (ResTy != MVT::i32 && ResTy != MVT::i64)
1020 unsigned Opcode = 0;
1021 if (ResTy == MVT::i32) {
1022 if (Pos +
Size <= 32)
1025 if (Pos +
Size <= 32)
1026 Opcode = Mips::DINS;
1027 else if (Pos < 32 && 1 <
Size)
1028 Opcode = Mips::DINSM;
1030 Opcode = Mips::DINSU;
1047 unsigned RdhwrOpc, DestReg;
1049 if (PtrVT == MVT::i32) {
1050 RdhwrOpc = Mips::RDHWR;
1053 RdhwrOpc = Mips::RDHWR64;
1054 DestReg = Mips::V1_64;
1086 APInt SplatValue, SplatUndef;
1087 unsigned SplatBitSize;
1101 switch (SplatBitSize) {
1105 LdiOp = Mips::LDI_B;
1106 ViaVecTy = MVT::v16i8;
1109 LdiOp = Mips::LDI_H;
1110 ViaVecTy = MVT::v8i16;
1113 LdiOp = Mips::LDI_W;
1114 ViaVecTy = MVT::v4i32;
1117 LdiOp = Mips::LDI_D;
1118 ViaVecTy = MVT::v2i64;
1134 ((
ABI.IsO32() && SplatBitSize < 64) ||
1135 (
ABI.IsN32() ||
ABI.IsN64()))) {
1141 bool Is32BitSplat =
ABI.IsO32() || SplatBitSize < 64;
1142 const unsigned ADDiuOp = Is32BitSplat ? Mips::ADDiu : Mips::DADDiu;
1143 const MVT SplatMVT = Is32BitSplat ? MVT::i32 : MVT::i64;
1145 Is32BitSplat ? Mips::ZERO : Mips::ZERO_64, SplatMVT);
1147 const unsigned FILLOp =
1150 : (SplatBitSize == 32 ? Mips::FILL_W
1151 : (SplatBitSize == 64 ? Mips::FILL_D : 0));
1153 assert(FILLOp != 0 &&
"Unknown FILL Op for splat synthesis!");
1154 assert((!
ABI.IsO32() || (FILLOp != Mips::FILL_D)) &&
1155 "Attempting to use fill.d on MIPS32!");
1163 }
else if (SplatValue.
isSignedIntN(32) && SplatBitSize == 32) {
1180 assert((
Hi ||
Lo) &&
"Zero case reached 32 bit case splat synthesis!");
1184 }
else if (SplatValue.
isSignedIntN(32) && SplatBitSize == 64 &&
1185 (
ABI.IsN32() ||
ABI.IsN64())) {
1204 Mips::SUBREG_TO_REG,
DL, MVT::i64,
1278 Highest ?
SDValue(HiRes, 0) : ZeroVal,
1287 Mips::INSERT_W,
DL, MVT::v4i32,
SDValue(Res, 0),
1288 (Highest || Higher) ?
SDValue(HiRes, 0) : ZeroVal,
1296 Mips::COPY_TO_REGCLASS,
DL, ViaVecTy,
SDValue(Res, 0),
1300 Mips::SPLATI_D,
DL, MVT::v2i64,
SDValue(Res, 0),
1302 }
else if (
ABI.IsN64() ||
ABI.IsN32()) {
1306 const bool ResNonZero =
Hi ||
Lo;
1310 Mips::SUBREG_TO_REG,
DL, MVT::i64,
1317 Mips::SUBREG_TO_REG,
DL, MVT::i64,
1332 const ConstantInt *Const32 = ConstantInt::get(Int32Ty, 32);
1339 }
else if (HiResNonZero) {
1341 Mips::DSLL32,
DL, MVT::i64,
SDValue(HiRes, 0),
1345 "Zero splat value handled by non-zero 64bit splat synthesis!");
1355 if (ResVecTy != ViaVecTy) {
1378bool MipsSEDAGToDAGISel::SelectInlineAsmMemoryOperand(
1380 std::vector<SDValue> &OutOps) {
1383 switch(ConstraintID) {
1390 OutOps.push_back(
Base);
1391 OutOps.push_back(
Offset);
1394 OutOps.push_back(
Op);
1404 OutOps.push_back(
Base);
1405 OutOps.push_back(
Offset);
1408 OutOps.push_back(
Op);
1417 OutOps.push_back(
Base);
1418 OutOps.push_back(
Offset);
1424 OutOps.push_back(
Base);
1425 OutOps.push_back(
Offset);
1430 OutOps.push_back(
Base);
1431 OutOps.push_back(
Offset);
1435 OutOps.push_back(
Op);
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static uint64_t getConstant(const Value *IndexValue)
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 popcount() const
Count the number of bits set.
unsigned getBitWidth() const
Return the number of bits in the APInt.
int32_t exactLogBase2() const
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.
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 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
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
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.
@ 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.
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.