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()));
158 if (SelectADDRrr(Addr,
Base, Disp))
165 CurDAG->getRegister(SP::G0, TLI->getPointerTy(CurDAG->getDataLayout()));
180bool SparcDAGToDAGISel::tryInlineAsm(SDNode *
N){
181 std::vector<SDValue> AsmNodeOperands;
182 InlineAsm::Flag
Flag;
184 unsigned NumOps =
N->getNumOperands();
199 for(
unsigned i = 0, e =
N->getGluedNode() ?
NumOps - 1 :
NumOps; i < e; ++i) {
201 AsmNodeOperands.push_back(
op);
207 Flag = InlineAsm::Flag(
C->getZExtValue());
215 if (
Flag.isImmKind()) {
217 AsmNodeOperands.push_back(
op);
221 const unsigned NumRegs =
Flag.getNumOperandRegisters();
226 bool IsTiedToChangedOp =
false;
230 IsTiedToChangedOp = OpChanged[DefIdx];
232 if (!
Flag.isRegUseKind() && !
Flag.isRegDefKind() &&
233 !
Flag.isRegDefEarlyClobberKind())
237 const bool HasRC =
Flag.hasRegClassConstraint(RC);
238 if ((!IsTiedToChangedOp && (!HasRC || RC != SP::IntRegsRegClassID))
242 assert((i+2 <
NumOps) &&
"Invalid number of operands in inline asm");
248 MachineRegisterInfo &MRI = MF->getRegInfo();
250 if (
Flag.isRegDefKind() ||
Flag.isRegDefEarlyClobberKind()) {
255 PairedReg = CurDAG->getRegister(GPVR, MVT::v2i32);
258 SDNode *GU =
N->getGluedUser();
259 SDValue RegCopy = CurDAG->getCopyFromReg(Chain, dl, GPVR, MVT::v2i32,
263 SDValue Sub0 = CurDAG->getTargetExtractSubreg(SP::sub_even, dl, MVT::i32,
265 SDValue Sub1 = CurDAG->getTargetExtractSubreg(SP::sub_odd, dl, MVT::i32,
267 SDValue T0 = CurDAG->getCopyToReg(Sub0, dl, Reg0, Sub0,
273 Ops.push_back(
T1.getValue(1));
274 CurDAG->UpdateNodeOperands(GU,
Ops);
281 SDValue T0 = CurDAG->getCopyFromReg(Chain, dl, Reg0, MVT::i32,
283 SDValue T1 = CurDAG->getCopyFromReg(Chain, dl, Reg1, MVT::i32,
286 CurDAG->getMachineNode(
287 TargetOpcode::REG_SEQUENCE, dl, MVT::v2i32,
289 CurDAG->getTargetConstant(SP::IntPairRegClassID, dl,
292 CurDAG->getTargetConstant(SP::sub_even, dl, MVT::i32),
294 CurDAG->getTargetConstant(SP::sub_odd, dl, MVT::i32),
301 PairedReg = CurDAG->getRegister(GPVR, MVT::v2i32);
302 Chain = CurDAG->getCopyToReg(
T1, dl, GPVR, Pair,
T1.getValue(1));
311 OpChanged[OpChanged.
size() -1 ] =
true;
312 Flag = InlineAsm::Flag(
Flag.getKind(), 1 );
313 if (IsTiedToChangedOp)
314 Flag.setMatchingOp(DefIdx);
316 Flag.setRegClass(SP::IntPairRegClassID);
318 AsmNodeOperands[AsmNodeOperands.size() -1] = CurDAG->getTargetConstant(
321 AsmNodeOperands.push_back(PairedReg);
328 AsmNodeOperands.push_back(Glue);
332 SelectInlineAsmMemoryOperands(AsmNodeOperands, SDLoc(
N));
335 CurDAG->getVTList(MVT::Other, MVT::Glue), AsmNodeOperands);
337 ReplaceNode(
N,
New.getNode());
341void SparcDAGToDAGISel::Select(SDNode *
N) {
343 if (
N->isMachineOpcode()) {
348 switch (
N->getOpcode()) {
356 case SPISD::GLOBAL_BASE_REG:
357 ReplaceNode(
N, getGlobalBaseReg());
363 if (
N->getValueType(0) == MVT::i64)
372 TopPart =
SDValue(CurDAG->getMachineNode(SP::SRAri, dl, MVT::i32, DivLHS,
373 CurDAG->getTargetConstant(31, dl, MVT::i32)),
376 TopPart = CurDAG->getRegister(SP::G0, MVT::i32);
378 TopPart = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, SP::Y, TopPart,
384 CurDAG->SelectNodeTo(
N, Opcode, MVT::i32, DivLHS, DivRHS, TopPart);
395bool SparcDAGToDAGISel::SelectInlineAsmMemoryOperand(
397 std::vector<SDValue> &OutOps) {
399 switch (ConstraintID) {
400 default:
return true;
401 case InlineAsm::ConstraintCode::o:
402 case InlineAsm::ConstraintCode::m:
403 if (!SelectADDRrr(
Op, Op0, Op1))
404 SelectADDRri(
Op, Op0, Op1);
408 OutOps.push_back(Op0);
409 OutOps.push_back(Op1);
417 return new SparcDAGToDAGISelLegacy(TM);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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
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)
@ 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...
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.