52 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
53 unsigned ConstraintID,
54 std::vector<SDValue> &OutOps)
override;
57 return "SPARC DAG->DAG Pattern Instruction Selection";
61 #include "SparcGenDAGISel.inc"
64 SDNode* getGlobalBaseReg();
69 SDNode* SparcDAGToDAGISel::getGlobalBaseReg() {
70 unsigned GlobalBaseReg = Subtarget->getInstrInfo()->getGlobalBaseReg(MF);
71 return CurDAG->getRegister(GlobalBaseReg,
72 TLI->getPointerTy(CurDAG->getDataLayout()))
76 bool SparcDAGToDAGISel::SelectADDRri(
SDValue Addr,
79 Base = CurDAG->getTargetFrameIndex(
80 FIN->getIndex(), TLI->getPointerTy(CurDAG->getDataLayout()));
91 if (isInt<13>(CN->getSExtValue())) {
93 dyn_cast<FrameIndexSDNode>(Addr.
getOperand(0))) {
95 Base = CurDAG->getTargetFrameIndex(
96 FIN->getIndex(), TLI->getPointerTy(CurDAG->getDataLayout()));
100 Offset = CurDAG->getTargetConstant(CN->getZExtValue(),
SDLoc(Addr),
117 Offset = CurDAG->getTargetConstant(0,
SDLoc(Addr),
MVT::i32);
130 if (isInt<13>(CN->getSExtValue()))
141 R2 = CurDAG->getRegister(SP::G0, TLI->getPointerTy(CurDAG->getDataLayout()));
157 bool SparcDAGToDAGISel::tryInlineAsm(
SDNode *
N){
158 std::vector<SDValue> AsmNodeOperands;
160 bool Changed =
false;
177 for(
unsigned i = 0, e = N->
getGluedNode() ? NumOps - 1 : NumOps;
i < e; ++
i) {
179 AsmNodeOperands.push_back(op);
185 Flag =
C->getZExtValue();
197 AsmNodeOperands.push_back(op);
206 bool IsTiedToChangedOp =
false;
210 IsTiedToChangedOp = OpChanged[DefIdx];
218 if ((!IsTiedToChangedOp && (!HasRC || RC != SP::IntRegsRegClassID))
222 assert((
i+2 < NumOps) &&
"Invalid number of operands in inline asm");
225 unsigned Reg0 = cast<RegisterSDNode>(V0)->
getReg();
226 unsigned Reg1 = cast<RegisterSDNode>(V1)->
getReg();
236 PairedReg = CurDAG->getRegister(GPVR,
MVT::v2i32);
244 SDValue Sub0 = CurDAG->getTargetExtractSubreg(SP::sub_even, dl,
MVT::i32,
246 SDValue Sub1 = CurDAG->getTargetExtractSubreg(SP::sub_odd, dl,
MVT::i32,
248 SDValue T0 = CurDAG->getCopyToReg(Sub0, dl, Reg0, Sub0,
255 CurDAG->UpdateNodeOperands(GU, Ops);
268 CurDAG->getMachineNode(
271 CurDAG->getTargetConstant(SP::IntPairRegClassID, dl,
274 CurDAG->getTargetConstant(SP::sub_even, dl,
MVT::i32),
276 CurDAG->getTargetConstant(SP::sub_odd, dl,
MVT::i32),
283 PairedReg = CurDAG->getRegister(GPVR,
MVT::v2i32);
284 Chain = CurDAG->getCopyToReg(T1, dl, GPVR, Pair, T1.
getValue(1));
293 OpChanged[OpChanged.
size() -1 ] =
true;
295 if (IsTiedToChangedOp)
300 AsmNodeOperands[AsmNodeOperands.size() -1] = CurDAG->getTargetConstant(
303 AsmNodeOperands.push_back(PairedReg);
310 AsmNodeOperands.push_back(Glue);
317 ReplaceNode(N, New.getNode());
336 ReplaceNode(N, getGlobalBaseReg());
351 TopPart =
SDValue(CurDAG->getMachineNode(SP::SRAri, dl, MVT::i32, DivLHS,
352 CurDAG->getTargetConstant(31, dl, MVT::i32)),
355 TopPart = CurDAG->getRegister(SP::G0, MVT::i32);
357 TopPart = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl,
SP::Y, TopPart,
366 Opcode == SP::SDIVrr) {
367 Opcode = SP::SDIVCCrr;
369 CurDAG->SelectNodeTo(N, Opcode, MVT::i32, DivLHS, DivRHS, TopPart);
381 SparcDAGToDAGISel::SelectInlineAsmMemoryOperand(
const SDValue &
Op,
382 unsigned ConstraintID,
383 std::vector<SDValue> &OutOps) {
385 switch (ConstraintID) {
386 default:
return true;
387 case InlineAsm::Constraint_i:
388 case InlineAsm::Constraint_o:
389 case InlineAsm::Constraint_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 SparcDAGToDAGISel(TM);
void push_back(const T &Elt)
SDValue getValue(unsigned R) const
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
static unsigned getFlagWord(unsigned Kind, unsigned NumOps)
SDNode * getGluedNode() const
If this node has a glue operand, return the node to which the glue operand points.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
void setNodeId(int Id)
Set unique node id.
static bool isUseOperandTiedToDef(unsigned Flag, unsigned &Idx)
isUseOperandTiedToDef - Return true if the flag of the inline asm operand indicates it is an use oper...
GlobalBaseReg - On Darwin, this node represents the result of the mflr at function entry...
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.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
INLINEASM - Represents an inline asm block.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Simple integer binary arithmetic operators.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
SDNode * getNode() const
get the SDNode which holds the desired result
unsigned const MachineRegisterInfo * MRI
const SDValue & getOperand(unsigned i) const
static unsigned getNumOperandRegisters(unsigned Flag)
getNumOperandRegisters - Extract the number of registers field from the inline asm operand flag...
unsigned getOpcode() const
static unsigned getKind(unsigned Flags)
FunctionPass class - This class is used to implement most global optimizations.
FunctionPass * createSparcISelDag(SparcTargetMachine &TM)
createSparcISelDag - This pass converts a legalized DAG into a SPARC-specific DAG, ready for instruction scheduling.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
SDNode * getGluedUser() const
If this node has a glue value with a user, return the user (there is at most one).
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
op_iterator op_begin() const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
static bool hasRegClassConstraint(unsigned Flag, unsigned &RC)
hasRegClassConstraint - Returns true if the flag contains a register class constraint.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
op_iterator op_end() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StringRef - Represent a constant reference to a string, i.e.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml","ocaml 3.10-compatible collector")
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
static unsigned getFlagWordForMatchingOp(unsigned InputFlag, unsigned MatchedOperandNo)
getFlagWordForMatchingOp - Augment an existing flag word returned by getFlagWord with information ind...
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode...