20#define DEBUG_TYPE "sparc-isel"
21#define PASS_NAME "SPARC DAG->DAG Pattern Instruction Selection"
38 SparcDAGToDAGISel() =
delete;
55 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
57 std::vector<SDValue> &OutOps)
override;
60#include "SparcGenDAGISel.inc"
63 SDNode* getGlobalBaseReg();
75char SparcDAGToDAGISelLegacy::ID = 0;
79SDNode* SparcDAGToDAGISel::getGlobalBaseReg() {
81 return CurDAG->getRegister(GlobalBaseReg,
82 TLI->getPointerTy(CurDAG->getDataLayout()))
86bool SparcDAGToDAGISel::SelectADDRri(
SDValue Addr,
89 Base = CurDAG->getTargetFrameIndex(
90 FIN->getIndex(), TLI->getPointerTy(CurDAG->getDataLayout()));
91 Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
102 if (FrameIndexSDNode *FIN =
105 Base = CurDAG->getTargetFrameIndex(
106 FIN->getIndex(), TLI->getPointerTy(CurDAG->getDataLayout()));
110 Offset = CurDAG->getSignedTargetConstant(CN->getSExtValue(),
111 SDLoc(Addr), MVT::i32);
127 Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
151 R2 = CurDAG->getRegister(SP::G0, TLI->getPointerTy(CurDAG->getDataLayout()));
167bool SparcDAGToDAGISel::tryInlineAsm(SDNode *
N){
168 std::vector<SDValue> AsmNodeOperands;
169 InlineAsm::Flag
Flag;
171 unsigned NumOps =
N->getNumOperands();
186 for(
unsigned i = 0, e =
N->getGluedNode() ?
NumOps - 1 :
NumOps; i < e; ++i) {
188 AsmNodeOperands.push_back(
op);
194 Flag = InlineAsm::Flag(
C->getZExtValue());
202 if (
Flag.isImmKind()) {
204 AsmNodeOperands.push_back(
op);
208 const unsigned NumRegs =
Flag.getNumOperandRegisters();
213 bool IsTiedToChangedOp =
false;
217 IsTiedToChangedOp = OpChanged[DefIdx];
219 if (!
Flag.isRegUseKind() && !
Flag.isRegDefKind() &&
220 !
Flag.isRegDefEarlyClobberKind())
224 const bool HasRC =
Flag.hasRegClassConstraint(RC);
225 if ((!IsTiedToChangedOp && (!HasRC || RC != SP::IntRegsRegClassID))
229 assert((i+2 <
NumOps) &&
"Invalid number of operands in inline asm");
235 MachineRegisterInfo &
MRI = MF->getRegInfo();
237 if (
Flag.isRegDefKind() ||
Flag.isRegDefEarlyClobberKind()) {
241 Register GPVR =
MRI.createVirtualRegister(&SP::IntPairRegClass);
242 PairedReg = CurDAG->getRegister(GPVR, MVT::v2i32);
245 SDNode *GU =
N->getGluedUser();
246 SDValue RegCopy = CurDAG->getCopyFromReg(Chain, dl, GPVR, MVT::v2i32,
250 SDValue Sub0 = CurDAG->getTargetExtractSubreg(SP::sub_even, dl, MVT::i32,
252 SDValue Sub1 = CurDAG->getTargetExtractSubreg(SP::sub_odd, dl, MVT::i32,
254 SDValue T0 = CurDAG->getCopyToReg(Sub0, dl, Reg0, Sub0,
260 Ops.push_back(
T1.getValue(1));
261 CurDAG->UpdateNodeOperands(GU,
Ops);
268 SDValue T0 = CurDAG->getCopyFromReg(Chain, dl, Reg0, MVT::i32,
270 SDValue T1 = CurDAG->getCopyFromReg(Chain, dl, Reg1, MVT::i32,
273 CurDAG->getMachineNode(
274 TargetOpcode::REG_SEQUENCE, dl, MVT::v2i32,
276 CurDAG->getTargetConstant(SP::IntPairRegClassID, dl,
279 CurDAG->getTargetConstant(SP::sub_even, dl, MVT::i32),
281 CurDAG->getTargetConstant(SP::sub_odd, dl, MVT::i32),
287 Register GPVR =
MRI.createVirtualRegister(&SP::IntPairRegClass);
288 PairedReg = CurDAG->getRegister(GPVR, MVT::v2i32);
289 Chain = CurDAG->getCopyToReg(
T1, dl, GPVR, Pair,
T1.getValue(1));
298 OpChanged[OpChanged.
size() -1 ] =
true;
299 Flag = InlineAsm::Flag(
Flag.getKind(), 1 );
300 if (IsTiedToChangedOp)
301 Flag.setMatchingOp(DefIdx);
303 Flag.setRegClass(SP::IntPairRegClassID);
305 AsmNodeOperands[AsmNodeOperands.size() -1] = CurDAG->getTargetConstant(
308 AsmNodeOperands.push_back(PairedReg);
315 AsmNodeOperands.push_back(Glue);
319 SelectInlineAsmMemoryOperands(AsmNodeOperands, SDLoc(
N));
322 CurDAG->getVTList(MVT::Other, MVT::Glue), AsmNodeOperands);
324 ReplaceNode(
N,
New.getNode());
328void SparcDAGToDAGISel::Select(SDNode *
N) {
330 if (
N->isMachineOpcode()) {
335 switch (
N->getOpcode()) {
338 case ISD::INLINEASM_BR: {
343 case SPISD::GLOBAL_BASE_REG:
344 ReplaceNode(
N, getGlobalBaseReg());
350 if (
N->getValueType(0) == MVT::i64)
359 TopPart =
SDValue(CurDAG->getMachineNode(SP::SRAri, dl, MVT::i32, DivLHS,
360 CurDAG->getTargetConstant(31, dl, MVT::i32)),
363 TopPart = CurDAG->getRegister(SP::G0, MVT::i32);
365 TopPart = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, SP::Y, TopPart,
371 CurDAG->SelectNodeTo(
N, Opcode, MVT::i32, DivLHS, DivRHS, TopPart);
382bool SparcDAGToDAGISel::SelectInlineAsmMemoryOperand(
384 std::vector<SDValue> &OutOps) {
386 switch (ConstraintID) {
387 default:
return true;
388 case InlineAsm::ConstraintCode::o:
389 case InlineAsm::ConstraintCode::m:
390 if (!SelectADDRrr(
Op, Op0, Op1))
391 SelectADDRri(
Op, Op0, Op1);
395 OutOps.push_back(Op0);
396 OutOps.push_back(Op1);
404 return new SparcDAGToDAGISelLegacy(TM);
unsigned const MachineRegisterInfo * MRI
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.
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)
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...
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.