Go to the documentation of this file.
26 #define DEBUG_TYPE "loongarch-isel-lowering"
74 const Align FunctionAlignment(4);
83 switch (
Op.getOpcode()) {
87 return lowerShiftLeftParts(
Op, DAG);
89 return lowerShiftRightParts(
Op, DAG,
true);
91 return lowerShiftRightParts(
Op, DAG,
false);
97 "Unexpected custom legalisation");
108 EVT VT = Lo.getValueType();
148 EVT VT =
Lo.getValueType();
228 switch (
N->getOpcode()) {
235 "Unexpected custom legalisation");
250 SDValue FirstOperand =
N->getOperand(0);
251 SDValue SecondOperand =
N->getOperand(1);
252 unsigned FirstOperandOpc = FirstOperand.
getOpcode();
253 EVT ValTy =
N->getValueType(0);
256 unsigned SMIdx, SMLen;
262 if (!(CN = dyn_cast<ConstantSDNode>(SecondOperand)) ||
273 if (!(CN = dyn_cast<ConstantSDNode>(FirstOperand.
getOperand(1))))
299 NewOperand = FirstOperand;
301 msb = lsb + SMLen - 1;
319 SDValue FirstOperand =
N->getOperand(0);
321 EVT ValTy =
N->getValueType(0);
324 unsigned MaskIdx, MaskLen;
330 !(CN = dyn_cast<ConstantSDNode>(FirstOperand.
getOperand(1))) ||
335 if (!(CN = dyn_cast<ConstantSDNode>(
N->getOperand(1))))
339 if (MaskIdx <= Shamt && Shamt <= MaskIdx + MaskLen - 1)
351 switch (
N->getOpcode()) {
367 #define NODE_NAME_CASE(node) \
368 case LoongArchISD::node: \
369 return "LoongArchISD::" #node;
378 #undef NODE_NAME_CASE
388 LoongArch::R7, LoongArch::R8, LoongArch::R9,
389 LoongArch::R10, LoongArch::R11};
391 LoongArch::F3, LoongArch::F4, LoongArch::F5,
392 LoongArch::F6, LoongArch::F7};
394 LoongArch::F0_64, LoongArch::F1_64, LoongArch::F2_64, LoongArch::F3_64,
395 LoongArch::F4_64, LoongArch::F5_64, LoongArch::F6_64, LoongArch::F7_64};
418 void LoongArchTargetLowering::analyzeInputArgs(
420 LoongArchCCAssignFn Fn)
const {
421 for (
unsigned i = 0,
e =
Ins.size();
i !=
e; ++
i) {
426 <<
EVT(ArgVT).getEVTString() <<
'\n');
432 void LoongArchTargetLowering::analyzeOutputArgs(
434 LoongArchCCAssignFn Fn)
const {
435 for (
unsigned i = 0,
e = Outs.size();
i !=
e; ++
i) {
436 MVT ArgVT = Outs[
i].VT;
440 <<
EVT(ArgVT).getEVTString() <<
"\n");
480 for (
unsigned i = 0,
e = ArgLocs.size();
i !=
e; ++
i)
491 return Outs.size() <= 2;
512 for (
unsigned i = 0,
e = RVLocs.size();
i <
e; ++
i) {
528 RetOps.push_back(Glue);
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
const LoongArchRegisterInfo * getRegisterInfo() const override
static LoongArchISD::NodeType getLoongArchWOpcode(unsigned Opcode)
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
This is an optimization pass for GlobalISel generic memory operations.
const char * getTargetNodeName(unsigned Opcode) const override
This method returns the name of a target specific DAG node.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
CCState - This class holds information needed while lowering arguments and return values.
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
SDNode * getNode() const
get the SDNode which holds the desired result
void addLoc(const CCValAssign &V)
unsigned getGRLen() const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Reg
All possible values of the reg field in the ModR/M byte.
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Represents one node in the SelectionDAG.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
Function Alias Analysis Results
LoongArchTargetLowering(const TargetMachine &TM, const LoongArchSubtarget &STI)
const MCPhysReg ArgFPR64s[]
LLVMContext * getContext() const
SDValue getRegister(unsigned Reg, EVT VT)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
CCValAssign - Represent assignment of one arg/retval to a location.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
bool isBeforeLegalizeOps() const
Register getLocReg() const
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
static SDValue performANDCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const LoongArchSubtarget &Subtarget)
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
This callback is invoked when a node result type is illegal for the target, and the operation was reg...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
@ AND
Bitwise operators - logical and, logical or, logical xor.
This struct is a compact representation of a valid (non-zero power of two) alignment.
static SDValue unpackFromRegLoc(SelectionDAG &DAG, SDValue Chain, const CCValAssign &VA, const SDLoc &DL, const LoongArchTargetLowering &TLI)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
#define NODE_NAME_CASE(node)
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, const SmallVectorImpl< SDValue > &OutVals, const SDLoc &DL, SelectionDAG &DAG) const override
This hook must be implemented to lower outgoing return values, described by the Outs array,...
static SDValue customLegalizeToWOp(SDNode *N, SelectionDAG &DAG, unsigned ExtOpc=ISD::ANY_EXTEND)
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
This is an important class for using LLVM in a threaded context.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl< ISD::InputArg > &Ins, const SDLoc &DL, SelectionDAG &DAG, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower the incoming (formal) arguments, described by the Ins array,...
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
const SDValue & getOperand(unsigned Num) const
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getValue(unsigned R) const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Primary interface to the complete machine description for the target machine.
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
uint64_t getZExtValue() const
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
@ C
C - The default llvm calling convention, compatible with C.
MCRegister AllocateReg(MCPhysReg Reg)
AllocateReg - Attempt to allocate one register.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const SDValue & getOperand(unsigned i) const
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Wrapper class representing virtual and physical registers.
const MCPhysReg ArgFPR32s[]
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
@ ZeroOrOneBooleanContent
@ ADD
Simple integer binary arithmetic operators.
static bool CC_LoongArch(unsigned ValNo, MVT ValVT, CCValAssign::LocInfo LocInfo, CCState &State)
static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const LoongArchSubtarget &Subtarget)
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
@ SHL
Shift and rotation operations.
static CCValAssign getReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP)
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
unsigned getOpcode() const
const char LLVMTargetMachineRef TM
MachineFunction & getMachineFunction() const
const MCPhysReg ArgGPRs[]
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, LLVMContext &Context) const override
This hook should be implemented to check whether the return values described by the Outs array can fi...