38 #define DEBUG_TYPE "mips-isel"
47 void MipsSEDAGToDAGISel::getAnalysisUsage(
AnalysisUsage &AU)
const {
52 void MipsSEDAGToDAGISel::addDSPCtrlRegOperands(
bool IsDef,
MachineInstr &
MI,
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);
78 unsigned MipsSEDAGToDAGISel::getMSACtrlReg(
const SDValue RegIdx)
const {
79 switch (cast<ConstantSDNode>(RegIdx)->getZExtValue()) {
82 case 0:
return Mips::MSAIR;
83 case 1:
return Mips::MSACSR;
84 case 2:
return Mips::MSAAccess;
85 case 3:
return Mips::MSASave;
86 case 4:
return Mips::MSAModify;
87 case 5:
return Mips::MSARequest;
88 case 6:
return Mips::MSAMap;
89 case 7:
return Mips::MSAUnmap;
95 unsigned DstReg = 0, ZeroReg = 0;
102 ZeroReg = Mips::ZERO;
103 }
else if ((MI.
getOpcode() == Mips::DADDiu) &&
107 ZeroReg = Mips::ZERO_64;
117 unsigned OpNo = U.getOperandNo();
150 RC = (ABI.
IsN64()) ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
165 BuildMI(MBB, I, DL, TII.
get(Mips::DADDu), V1).addReg(V0)
222 .addReg(Mips::V0).
addReg(Mips::T9);
225 void MipsSEDAGToDAGISel::processFunctionAfterISel(
MachineFunction &MF) {
226 initGlobalBaseReg(MF);
230 for (
auto &MBB: MF) {
231 for (
auto &MI: MBB) {
234 addDSPCtrlRegOperands(
false, MI, MF);
237 addDSPCtrlRegOperands(
true, MI, MF);
240 replaceUsesWithZeroReg(MRI, MI);
246 void MipsSEDAGToDAGISel::selectAddESubE(
unsigned MOp,
SDValue InFlag,
249 unsigned Opc = InFlag.
getOpcode(); (void)Opc;
253 "(ADD|SUB)E flag operand must come from (ADD|SUB)C/E insn");
255 unsigned SLTuOp = Mips::SLTu, ADDuOp = Mips::ADDu;
257 SLTuOp = Mips::SLTu64;
258 ADDuOp = Mips::DADDu;
289 bool MipsSEDAGToDAGISel::selectAddrFrameIndex(
SDValue Addr,
SDValue &Base,
302 bool MipsSEDAGToDAGISel::selectAddrFrameIndexOffset(
304 unsigned ShiftAmount = 0)
const {
312 dyn_cast<FrameIndexSDNode>(Addr.
getOperand(0)))
332 bool MipsSEDAGToDAGISel::selectAddrRegImm(
SDValue Addr,
SDValue &Base,
335 if (selectAddrFrameIndex(Addr, Base, Offset))
352 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 16))
368 if (isa<ConstantPoolSDNode>(Opnd0) || isa<GlobalAddressSDNode>(Opnd0) ||
369 isa<JumpTableSDNode>(Opnd0)) {
382 bool MipsSEDAGToDAGISel::selectAddrDefault(
SDValue Addr,
SDValue &Base,
389 bool MipsSEDAGToDAGISel::selectIntAddr(
SDValue Addr,
SDValue &Base,
391 return selectAddrRegImm(Addr, Base, Offset) ||
392 selectAddrDefault(Addr, Base, Offset);
395 bool MipsSEDAGToDAGISel::selectAddrRegImm9(
SDValue Addr,
SDValue &Base,
397 if (selectAddrFrameIndex(Addr, Base, Offset))
400 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 9))
407 bool MipsSEDAGToDAGISel::selectAddrRegImm11(
SDValue Addr,
SDValue &Base,
409 if (selectAddrFrameIndex(Addr, Base, Offset))
412 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 11))
419 bool MipsSEDAGToDAGISel::selectAddrRegImm12(
SDValue Addr,
SDValue &Base,
421 if (selectAddrFrameIndex(Addr, Base, Offset))
424 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 12))
430 bool MipsSEDAGToDAGISel::selectAddrRegImm16(
SDValue Addr,
SDValue &Base,
432 if (selectAddrFrameIndex(Addr, Base, Offset))
435 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 16))
441 bool MipsSEDAGToDAGISel::selectIntAddr11MM(
SDValue Addr,
SDValue &Base,
443 return selectAddrRegImm11(Addr, Base, Offset) ||
444 selectAddrDefault(Addr, Base, Offset);
447 bool MipsSEDAGToDAGISel::selectIntAddr12MM(
SDValue Addr,
SDValue &Base,
449 return selectAddrRegImm12(Addr, Base, Offset) ||
450 selectAddrDefault(Addr, Base, Offset);
453 bool MipsSEDAGToDAGISel::selectIntAddr16MM(
SDValue Addr,
SDValue &Base,
455 return selectAddrRegImm16(Addr, Base, Offset) ||
456 selectAddrDefault(Addr, Base, Offset);
459 bool MipsSEDAGToDAGISel::selectIntAddrLSL2MM(
SDValue Addr,
SDValue &Base,
461 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 7)) {
462 if (isa<FrameIndexSDNode>(Base))
467 return (CnstOff == (CnstOff & 0x3c));
475 if (selectAddrRegImm(Addr, Base, Offset))
478 return selectAddrDefault(Addr, Base, Offset);
481 bool MipsSEDAGToDAGISel::selectIntAddrSImm10(
SDValue Addr,
SDValue &Base,
484 if (selectAddrFrameIndex(Addr, Base, Offset))
487 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10))
490 return selectAddrDefault(Addr, Base, Offset);
493 bool MipsSEDAGToDAGISel::selectIntAddrSImm10Lsl1(
SDValue Addr,
SDValue &Base,
495 if (selectAddrFrameIndex(Addr, Base, Offset))
498 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10, 1))
501 return selectAddrDefault(Addr, Base, Offset);
504 bool MipsSEDAGToDAGISel::selectIntAddrSImm10Lsl2(
SDValue Addr,
SDValue &Base,
506 if (selectAddrFrameIndex(Addr, Base, Offset))
509 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10, 2))
512 return selectAddrDefault(Addr, Base, Offset);
515 bool MipsSEDAGToDAGISel::selectIntAddrSImm10Lsl3(
SDValue Addr,
SDValue &Base,
517 if (selectAddrFrameIndex(Addr, Base, Offset))
520 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10, 3))
523 return selectAddrDefault(Addr, Base, Offset);
531 bool MipsSEDAGToDAGISel::selectVSplat(
SDNode *
N,
APInt &Imm,
532 unsigned MinSizeInBits)
const {
541 APInt SplatValue, SplatUndef;
542 unsigned SplatBitSize;
545 if (!Node->
isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
570 bool MipsSEDAGToDAGISel::
572 unsigned ImmBitSize)
const {
583 (!Signed && ImmValue.
isIntN(ImmBitSize))) {
593 bool MipsSEDAGToDAGISel::
595 return selectVSplatCommon(N, Imm,
false, 1);
598 bool MipsSEDAGToDAGISel::
600 return selectVSplatCommon(N, Imm,
false, 2);
603 bool MipsSEDAGToDAGISel::
605 return selectVSplatCommon(N, Imm,
false, 3);
609 bool MipsSEDAGToDAGISel::
611 return selectVSplatCommon(N, Imm,
false, 4);
615 bool MipsSEDAGToDAGISel::
617 return selectVSplatCommon(N, Imm,
false, 5);
621 bool MipsSEDAGToDAGISel::
623 return selectVSplatCommon(N, Imm,
false, 6);
627 bool MipsSEDAGToDAGISel::
629 return selectVSplatCommon(N, Imm,
false, 8);
633 bool MipsSEDAGToDAGISel::
635 return selectVSplatCommon(N, Imm,
true, 5);
648 bool MipsSEDAGToDAGISel::selectVSplatUimmPow2(
SDValue N,
SDValue &Imm)
const {
679 bool MipsSEDAGToDAGISel::selectVSplatMaskL(
SDValue N,
SDValue &Imm)
const {
691 if (ImmValue == ~(~ImmValue & ~(~ImmValue + 1))) {
713 bool MipsSEDAGToDAGISel::selectVSplatMaskR(
SDValue N,
SDValue &Imm)
const {
724 if (ImmValue == (ImmValue & ~(ImmValue + 1))) {
734 bool MipsSEDAGToDAGISel::selectVSplatUimmInvPow2(
SDValue N,
744 int32_t Log2 = (~ImmValue).exactLogBase2();
755 bool MipsSEDAGToDAGISel::trySelect(
SDNode *Node) {
769 selectAddESubE(Opc, InFlag, InFlag.
getOperand(0), DL, Node);
778 selectAddESubE(Opc, InFlag, InFlag.
getValue(0), DL, Node);
817 AnalyzeImm.
Analyze(Imm, Size,
false);
828 if (Inst->Opc == Mips::LUi64)
837 for (++Inst; Inst != Seq.
end(); ++Inst) {
849 switch (cast<ConstantSDNode>(Node->
getOperand(1))->getZExtValue()) {
853 case Intrinsic::mips_cfcmsa: {
866 switch (cast<ConstantSDNode>(Node->
getOperand(0))->getZExtValue()) {
870 case Intrinsic::mips_move_v:
882 switch (cast<ConstantSDNode>(Node->
getOperand(1))->getZExtValue()) {
886 case Intrinsic::mips_ctcmsa: {
891 getMSACtrlReg(RegIdx), Value);
901 unsigned RdhwrOpc, DestReg;
904 RdhwrOpc = Mips::RDHWR;
907 RdhwrOpc = Mips::RDHWR64;
908 DestReg = Mips::V1_64;
936 APInt SplatValue, SplatUndef;
937 unsigned SplatBitSize;
951 switch (SplatBitSize) {
972 if (!SplatValue.isSignedIntN(10))
980 if (ResVecTy != ViaVecTy) {
1003 bool MipsSEDAGToDAGISel::
1004 SelectInlineAsmMemoryOperand(
const SDValue &
Op,
unsigned ConstraintID,
1005 std::vector<SDValue> &OutOps) {
1008 switch(ConstraintID) {
1013 OutOps.push_back(Op);
1017 if (selectAddrRegImm16(Op, Base, Offset)) {
1018 OutOps.push_back(Base);
1019 OutOps.push_back(Offset);
1022 OutOps.push_back(Op);
1031 if (selectAddrRegImm9(Op, Base, Offset)) {
1032 OutOps.push_back(Base);
1033 OutOps.push_back(Offset);
1036 OutOps.push_back(Op);
1044 if (selectAddrRegImm12(Op, Base, Offset)) {
1045 OutOps.push_back(Base);
1046 OutOps.push_back(Offset);
1051 if (selectAddrRegImm9(Op, Base, Offset)) {
1052 OutOps.push_back(Base);
1053 OutOps.push_back(Offset);
1056 }
else if (selectAddrRegImm16(Op, Base, Offset)) {
1058 OutOps.push_back(Base);
1059 OutOps.push_back(Offset);
1063 OutOps.push_back(Op);
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
unsigned getValueSizeInBits(unsigned ResNo) const
Returns MVT::getSizeInBits(getValueType(ResNo)).
SDValue getValue(unsigned R) const
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
bool isExactlyValue(double V) const
We don't rely on operator== working on double values, as it returns true for things that are clearly ...
FunctionPass * createMipsSEISelDag(MipsTargetMachine &TM, CodeGenOpt::Level OptLevel)
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
void addLiveIn(unsigned Reg, unsigned vreg=0)
addLiveIn - Add the specified register as a live-in.
Carry-setting nodes for multiple precision addition and subtraction.
bool isPseudo(QueryType Type=IgnoreBundle) const
Return true if this is a pseudo instruction that doesn't correspond to a real machine instruction...
const MipsInstrInfo * getInstrInfo() const override
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
unsigned getID() const
Return the register class ID number.
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
const SDValue & getOperand(unsigned Num) const
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
return AArch64::GPR64RegClass contains(Reg)
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
GlobalBaseReg - On Darwin, this node represents the result of the mflr at function entry...
AnalysisUsage & addRequired()
static use_iterator use_end()
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
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), MachineInstr opcode, and operands.
const TargetLowering * TLI
const TargetLowering * getTargetLowering() const
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
Reg
All possible values of the reg field in the ModR/M byte.
bool isIntN(unsigned N) const
Check if this APInt has an N-bits unsigned integer value.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
MO_ABS_HI/LO - Represents the hi or low part of an absolute symbol address.
EVT getVectorElementType() const
getVectorElementType - Given a vector type, return the type of each element.
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...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const MachineBasicBlock & front() const
SDValue getTargetFrameIndex(int FI, EVT VT)
Simple integer binary arithmetic operators.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
const DataLayout & getDataLayout() const
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
Flag
These should be considered private to the implementation of the MCInstrDesc class.
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a vector with the specified, possibly variable...
TargetInstrInfo - Interface to description of machine instruction set.
MachineRegisterInfo * RegInfo
SDNode * getNode() const
get the SDNode which holds the desired result
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
void addLiveIn(MCPhysReg PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
unsigned const MachineRegisterInfo * MRI
const MipsSubtarget * Subtarget
Keep a pointer to the MipsSubtarget around so that we can make the right decision when generating cod...
MVT - Machine Value Type.
const SDValue & getOperand(unsigned i) const
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
const MachineOperand & getOperand(unsigned i) const
Carry-using nodes for multiple precision addition and subtraction.
Represent the analysis usage information of a pass.
bool isPositionIndependent() const
unsigned getBitWidth() const
Return the number of bits in the APInt.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
unsigned getOpcode() const
FunctionPass class - This class is used to implement most global optimizations.
unsigned countPopulation() const
Count the number of bits set.
bool inMicroMipsMode() const
bool inMips16Mode() const
EVT - Extended Value Type.
bool isIntN(unsigned N, int64_t x)
isIntN - Checks if an signed integer fits into the given (dynamic) bit width.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
constexpr bool isInt< 32 >(int64_t x)
bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side...
unsigned getGlobalBaseReg()
SuperClass::const_iterator const_iterator
double Log2(double Value)
Log2 - This function returns the log base 2 of the specified value.
SDNode * SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT)
These are used for target selectors to mutate the specified node to have the specified return type...
MachineOperand class - Representation of each machine instruction operand.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
int32_t exactLogBase2() const
Represents one node in the SelectionDAG.
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
Class for arbitrary precision integers.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
A "pseudo-class" with methods for operating on BUILD_VECTORs.
int64_t getSExtValue() const
virtual const TargetRegisterClass * getRegClassFor(MVT VT) const
Return the register class that should be used for the specified value type.
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned char TargetFlags=0) const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
use_iterator use_begin(unsigned RegNo) const
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned char TargetFlags=0) const
unsigned getSizeInBits() const
getSizeInBits - Return the size of the specified value type in bits.
void setReg(unsigned Reg)
Change the register this operand corresponds to.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
bool globalBaseRegSet() const
EVT getValueType() const
Return the ValueType of the referenced return value.
bool is128BitVector() const
is128BitVector - Return true if this is a 128-bit vector type.
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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...
LLVM Value Representation.
SDValue getRegister(unsigned Reg, EVT VT)
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
bool isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx=nullptr) const
Return true if the use operand of the specified index is tied to a def operand.
void ReplaceNode(SDNode *F, SDNode *T)
Replace all uses of F with T, then remove F from the DAG.
Legacy analysis pass which computes a DominatorTree.
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const TargetInstrInfo * TII
reg_begin/reg_end - Provide iteration support to walk over all definitions and uses of a register wit...
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
MVT getSimpleVT() const
getSimpleVT - Return the SimpleValueType held in the specified simple EVT.
uint64_t getZExtValue() const