20#define DEBUG_TYPE "sparc-isel"
21#define PASS_NAME "SPARC DAG->DAG Pattern Instruction Selection"
38 SparcDAGToDAGISel() =
delete;
56 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
58 std::vector<SDValue> &OutOps)
override;
61#include "SparcGenDAGISel.inc"
64 SDNode* getGlobalBaseReg();
76char SparcDAGToDAGISelLegacy::ID = 0;
80SDNode* SparcDAGToDAGISel::getGlobalBaseReg() {
82 return CurDAG->getRegister(GlobalBaseReg,
83 TLI->getPointerTy(CurDAG->getDataLayout()))
87bool SparcDAGToDAGISel::SelectADDRri(
SDValue Addr,
90 Base = CurDAG->getTargetFrameIndex(
91 FIN->getIndex(), TLI->getPointerTy(CurDAG->getDataLayout()));
92 Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
103 if (FrameIndexSDNode *FIN =
106 Base = CurDAG->getTargetFrameIndex(
107 FIN->getIndex(), TLI->getPointerTy(CurDAG->getDataLayout()));
111 Offset = CurDAG->getSignedTargetConstant(CN->getSExtValue(),
112 SDLoc(Addr), MVT::i32);
128 Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
152 R2 = CurDAG->getRegister(SP::G0, TLI->getPointerTy(CurDAG->getDataLayout()));
162 return SelectADDRrr(Addr,
Base, Disp);
168 CurDAG->getRegister(SP::G0, TLI->getPointerTy(CurDAG->getDataLayout()));
183bool SparcDAGToDAGISel::tryInlineAsm(SDNode *
N){
184 std::vector<SDValue> AsmNodeOperands;
185 InlineAsm::Flag
Flag;
187 unsigned NumOps =
N->getNumOperands();
202 for(
unsigned i = 0, e =
N->getGluedNode() ?
NumOps - 1 :
NumOps; i < e; ++i) {
204 AsmNodeOperands.push_back(
op);
210 Flag = InlineAsm::Flag(
C->getZExtValue());
218 if (
Flag.isImmKind()) {
220 AsmNodeOperands.push_back(
op);
224 const unsigned NumRegs =
Flag.getNumOperandRegisters();
229 bool IsTiedToChangedOp =
false;
233 IsTiedToChangedOp = OpChanged[DefIdx];
235 if (!
Flag.isRegUseKind() && !
Flag.isRegDefKind() &&
236 !
Flag.isRegDefEarlyClobberKind())
240 const bool HasRC =
Flag.hasRegClassConstraint(RC);
241 if ((!IsTiedToChangedOp && (!HasRC || RC != SP::IntRegsRegClassID))
245 assert((i+2 <
NumOps) &&
"Invalid number of operands in inline asm");
251 MachineRegisterInfo &MRI = MF->getRegInfo();
253 if (
Flag.isRegDefKind() ||
Flag.isRegDefEarlyClobberKind()) {
258 PairedReg = CurDAG->getRegister(GPVR, MVT::v2i32);
261 SDNode *GU =
N->getGluedUser();
262 SDValue RegCopy = CurDAG->getCopyFromReg(Chain, dl, GPVR, MVT::v2i32,
266 SDValue Sub0 = CurDAG->getTargetExtractSubreg(SP::sub_even, dl, MVT::i32,
268 SDValue Sub1 = CurDAG->getTargetExtractSubreg(SP::sub_odd, dl, MVT::i32,
270 SDValue T0 = CurDAG->getCopyToReg(Sub0, dl, Reg0, Sub0,
276 Ops.push_back(
T1.getValue(1));
277 CurDAG->UpdateNodeOperands(GU,
Ops);
284 SDValue T0 = CurDAG->getCopyFromReg(Chain, dl, Reg0, MVT::i32,
286 SDValue T1 = CurDAG->getCopyFromReg(Chain, dl, Reg1, MVT::i32,
289 CurDAG->getMachineNode(
290 TargetOpcode::REG_SEQUENCE, dl, MVT::v2i32,
292 CurDAG->getTargetConstant(SP::IntPairRegClassID, dl,
295 CurDAG->getTargetConstant(SP::sub_even, dl, MVT::i32),
297 CurDAG->getTargetConstant(SP::sub_odd, dl, MVT::i32),
304 PairedReg = CurDAG->getRegister(GPVR, MVT::v2i32);
305 Chain = CurDAG->getCopyToReg(
T1, dl, GPVR, Pair,
T1.getValue(1));
314 OpChanged[OpChanged.
size() -1 ] =
true;
315 Flag = InlineAsm::Flag(
Flag.getKind(), 1 );
316 if (IsTiedToChangedOp)
317 Flag.setMatchingOp(DefIdx);
319 Flag.setRegClass(SP::IntPairRegClassID);
321 AsmNodeOperands[AsmNodeOperands.size() -1] = CurDAG->getTargetConstant(
324 AsmNodeOperands.push_back(PairedReg);
331 AsmNodeOperands.push_back(Glue);
335 SelectInlineAsmMemoryOperands(AsmNodeOperands, SDLoc(
N));
338 CurDAG->getVTList(MVT::Other, MVT::Glue), AsmNodeOperands);
340 ReplaceNode(
N,
New.getNode());
344void SparcDAGToDAGISel::Select(SDNode *
N) {
346 if (
N->isMachineOpcode()) {
351 switch (
N->getOpcode()) {
359 case SPISD::GLOBAL_BASE_REG:
360 ReplaceNode(
N, getGlobalBaseReg());
366 if (
N->getValueType(0) == MVT::i64)
375 TopPart =
SDValue(CurDAG->getMachineNode(SP::SRAri, dl, MVT::i32, DivLHS,
376 CurDAG->getTargetConstant(31, dl, MVT::i32)),
379 TopPart = CurDAG->getRegister(SP::G0, MVT::i32);
381 TopPart = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, SP::Y, TopPart,
387 CurDAG->SelectNodeTo(
N, Opcode, MVT::i32, DivLHS, DivRHS, TopPart);
398bool SparcDAGToDAGISel::SelectInlineAsmMemoryOperand(
400 std::vector<SDValue> &OutOps) {
402 switch (ConstraintID) {
403 default:
return true;
404 case InlineAsm::ConstraintCode::o:
405 case InlineAsm::ConstraintCode::m:
406 if (!SelectADDRrr(
Op, Op0, Op1))
407 SelectADDRri(
Op, Op0, Op1);
411 OutOps.push_back(Op0);
412 OutOps.push_back(Op1);
420 return new SparcDAGToDAGISelLegacy(TM);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
FunctionPass class - This class is used to implement most global optimizations.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Wrapper class representing virtual and physical registers.
Represents one node in the SelectionDAG.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
op_iterator op_end() const
op_iterator op_begin() const
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
const SDValue & getOperand(unsigned i) const
unsigned getOpcode() const
unsigned getNumOperands() const
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
virtual bool runOnMachineFunction(MachineFunction &mf)
void push_back(const T &Elt)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ ADD
Simple integer binary arithmetic operators.
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ INLINEASM_BR
INLINEASM_BR - Branching version of inline asm. Used by asm-goto.
@ INLINEASM
INLINEASM - Represents an inline asm block.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
This is an optimization pass for GlobalISel generic memory operations.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
FunctionPass * createSparcISelDag(SparcTargetMachine &TM)
createSparcISelDag - This pass converts a legalized DAG into a SPARC-specific DAG,...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.