22#define DEBUG_TYPE "sparc-isel"
23#define PASS_NAME "SPARC DAG->DAG Pattern Instruction Selection"
41 SparcDAGToDAGISel() =
delete;
59 unsigned ConstraintID,
60 std::vector<SDValue> &OutOps)
override;
63#include "SparcGenDAGISel.inc"
66 SDNode* getGlobalBaseReg();
71char SparcDAGToDAGISel::ID = 0;
75SDNode* SparcDAGToDAGISel::getGlobalBaseReg() {
77 return CurDAG->getRegister(GlobalBaseReg,
78 TLI->getPointerTy(CurDAG->getDataLayout()))
85 Base = CurDAG->getTargetFrameIndex(
86 FIN->getIndex(), TLI->getPointerTy(CurDAG->getDataLayout()));
97 if (isInt<13>(CN->getSExtValue())) {
99 dyn_cast<FrameIndexSDNode>(
Addr.getOperand(0))) {
101 Base = CurDAG->getTargetFrameIndex(
102 FIN->getIndex(), TLI->getPointerTy(CurDAG->getDataLayout()));
136 if (isInt<13>(CN->getSExtValue()))
141 R1 =
Addr.getOperand(0);
147 R2 = CurDAG->getRegister(SP::G0, TLI->getPointerTy(CurDAG->getDataLayout()));
163bool SparcDAGToDAGISel::tryInlineAsm(
SDNode *
N){
164 std::vector<SDValue> AsmNodeOperands;
166 bool Changed =
false;
167 unsigned NumOps =
N->getNumOperands();
182 for(
unsigned i = 0, e =
N->getGluedNode() ? NumOps - 1 : NumOps; i < e; ++i) {
184 AsmNodeOperands.push_back(
op);
190 Flag =
C->getZExtValue();
202 AsmNodeOperands.push_back(
op);
211 bool IsTiedToChangedOp =
false;
215 IsTiedToChangedOp = OpChanged[DefIdx];
223 if ((!IsTiedToChangedOp && (!HasRC || RC != SP::IntRegsRegClassID))
227 assert((i+2 < NumOps) &&
"Invalid number of operands in inline asm");
230 Register Reg0 = cast<RegisterSDNode>(V0)->getReg();
231 Register Reg1 = cast<RegisterSDNode>(V1)->getReg();
240 Register GPVR =
MRI.createVirtualRegister(&SP::IntPairRegClass);
241 PairedReg = CurDAG->getRegister(GPVR,
MVT::v2i32);
244 SDNode *GU =
N->getGluedUser();
249 SDValue Sub0 = CurDAG->getTargetExtractSubreg(SP::sub_even, dl,
MVT::i32,
251 SDValue Sub1 = CurDAG->getTargetExtractSubreg(SP::sub_odd, dl,
MVT::i32,
253 SDValue T0 = CurDAG->getCopyToReg(Sub0, dl, Reg0, Sub0,
259 Ops.push_back(
T1.getValue(1));
260 CurDAG->UpdateNodeOperands(GU, Ops);
273 CurDAG->getMachineNode(
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;
300 if (IsTiedToChangedOp)
305 AsmNodeOperands[AsmNodeOperands.size() -1] = CurDAG->getTargetConstant(
308 AsmNodeOperands.push_back(PairedReg);
315 AsmNodeOperands.push_back(Glue);
319 SelectInlineAsmMemoryOperands(AsmNodeOperands,
SDLoc(
N));
324 ReplaceNode(
N,
New.getNode());
328void SparcDAGToDAGISel::Select(
SDNode *
N) {
330 if (
N->isMachineOpcode()) {
335 switch (
N->getOpcode()) {
344 ReplaceNode(
N, getGlobalBaseReg());
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,
370 unsigned Opcode =
N->getOpcode() ==
ISD::SDIV ? SP::SDIVrr : SP::UDIVrr;
371 CurDAG->SelectNodeTo(
N, Opcode,
MVT::i32, DivLHS, DivRHS, TopPart);
383SparcDAGToDAGISel::SelectInlineAsmMemoryOperand(
const SDValue &Op,
384 unsigned ConstraintID,
385 std::vector<SDValue> &OutOps) {
387 switch (ConstraintID) {
388 default:
return true;
391 if (!SelectADDRrr(Op, Op0, Op1))
392 SelectADDRri(Op, Op0, Op1);
396 OutOps.push_back(Op0);
397 OutOps.push_back(Op1);
405 return new SparcDAGToDAGISel(
TM);
unsigned const MachineRegisterInfo * MRI
amdgpu AMDGPU Register Bank Select
const char LLVMTargetMachineRef TM
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
FunctionPass class - This class is used to implement most global optimizations.
static unsigned getFlagWord(unsigned Kind, unsigned NumOps)
static unsigned getNumOperandRegisters(unsigned Flag)
getNumOperandRegisters - Extract the number of registers field from the inline asm operand flag.
@ Kind_RegDefEarlyClobber
static bool isUseOperandTiedToDef(unsigned Flag, unsigned &Idx)
isUseOperandTiedToDef - Return true if the flag of the inline asm operand indicates it is an use oper...
static bool hasRegClassConstraint(unsigned Flag, unsigned &RC)
hasRegClassConstraint - Returns true if the flag contains a register class constraint.
static unsigned getFlagWordForMatchingOp(unsigned InputFlag, unsigned MatchedOperandNo)
getFlagWordForMatchingOp - Augment an existing flag word returned by getFlagWord with information ind...
static unsigned getKind(unsigned Flags)
static unsigned getFlagWordForRegClass(unsigned InputFlag, unsigned RC)
getFlagWordForRegClass - Augment an existing flag word returned by getFlagWord with the required regi...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
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
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, std::vector< SDValue > &OutOps)
SelectInlineAsmMemoryOperand - Select the specified address as a target addressing mode,...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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.
FunctionPass * createSparcISelDag(SparcTargetMachine &TM)
createSparcISelDag - This pass converts a legalized DAG into a SPARC-specific DAG,...