def SDNPSideEffect : SDNodeProperty; // Sets 'HasUnmodelledSideEffects'.
def SDNPMemOperand : SDNodeProperty; // Touches memory, has assoc MemOperand
def SDNPVariadic : SDNodeProperty; // Node has variable arguments.
+def SDNPWantRoot : SDNodeProperty; // ComplexPattern gets the root of match
+def SDNPWantParent : SDNodeProperty; // ComplexPattern gets the parent
//===----------------------------------------------------------------------===//
// Selection DAG Node definitions.
SDNode *Select(SDNode *N);
- bool SelectShifterOperandReg(SDNode *Op, SDValue N, SDValue &A,
+ bool SelectShifterOperandReg(SDValue N, SDValue &A,
SDValue &B, SDValue &C);
- bool SelectAddrMode2(SDNode *Op, SDValue N, SDValue &Base,
+ bool SelectAddrMode2(SDValue N, SDValue &Base,
SDValue &Offset, SDValue &Opc);
bool SelectAddrMode2Offset(SDNode *Op, SDValue N,
SDValue &Offset, SDValue &Opc);
- bool SelectAddrMode3(SDNode *Op, SDValue N, SDValue &Base,
+ bool SelectAddrMode3(SDValue N, SDValue &Base,
SDValue &Offset, SDValue &Opc);
bool SelectAddrMode3Offset(SDNode *Op, SDValue N,
SDValue &Offset, SDValue &Opc);
- bool SelectAddrMode4(SDNode *Op, SDValue N, SDValue &Addr,
- SDValue &Mode);
- bool SelectAddrMode5(SDNode *Op, SDValue N, SDValue &Base,
+ bool SelectAddrMode4(SDValue N, SDValue &Addr, SDValue &Mode);
+ bool SelectAddrMode5(SDValue N, SDValue &Base,
SDValue &Offset);
- bool SelectAddrMode6(SDNode *Op, SDValue N, SDValue &Addr, SDValue &Align);
+ bool SelectAddrMode6(SDValue N, SDValue &Addr, SDValue &Align);
- bool SelectAddrModePC(SDNode *Op, SDValue N, SDValue &Offset,
+ bool SelectAddrModePC(SDValue N, SDValue &Offset,
SDValue &Label);
- bool SelectThumbAddrModeRR(SDNode *Op, SDValue N, SDValue &Base,
- SDValue &Offset);
- bool SelectThumbAddrModeRI5(SDNode *Op, SDValue N, unsigned Scale,
+ bool SelectThumbAddrModeRR(SDValue N, SDValue &Base, SDValue &Offset);
+ bool SelectThumbAddrModeRI5(SDValue N, unsigned Scale,
SDValue &Base, SDValue &OffImm,
SDValue &Offset);
- bool SelectThumbAddrModeS1(SDNode *Op, SDValue N, SDValue &Base,
+ bool SelectThumbAddrModeS1(SDValue N, SDValue &Base,
SDValue &OffImm, SDValue &Offset);
- bool SelectThumbAddrModeS2(SDNode *Op, SDValue N, SDValue &Base,
+ bool SelectThumbAddrModeS2(SDValue N, SDValue &Base,
SDValue &OffImm, SDValue &Offset);
- bool SelectThumbAddrModeS4(SDNode *Op, SDValue N, SDValue &Base,
+ bool SelectThumbAddrModeS4(SDValue N, SDValue &Base,
SDValue &OffImm, SDValue &Offset);
- bool SelectThumbAddrModeSP(SDNode *Op, SDValue N, SDValue &Base,
- SDValue &OffImm);
+ bool SelectThumbAddrModeSP(SDValue N, SDValue &Base, SDValue &OffImm);
- bool SelectT2ShifterOperandReg(SDNode *Op, SDValue N,
+ bool SelectT2ShifterOperandReg(SDValue N,
SDValue &BaseReg, SDValue &Opc);
- bool SelectT2AddrModeImm12(SDNode *Op, SDValue N, SDValue &Base,
- SDValue &OffImm);
- bool SelectT2AddrModeImm8(SDNode *Op, SDValue N, SDValue &Base,
+ bool SelectT2AddrModeImm12(SDValue N, SDValue &Base, SDValue &OffImm);
+ bool SelectT2AddrModeImm8(SDValue N, SDValue &Base,
SDValue &OffImm);
bool SelectT2AddrModeImm8Offset(SDNode *Op, SDValue N,
SDValue &OffImm);
- bool SelectT2AddrModeSoReg(SDNode *Op, SDValue N, SDValue &Base,
+ bool SelectT2AddrModeSoReg(SDValue N, SDValue &Base,
SDValue &OffReg, SDValue &ShImm);
inline bool Pred_so_imm(SDNode *inN) const {
}
-bool ARMDAGToDAGISel::SelectShifterOperandReg(SDNode *Op,
- SDValue N,
+bool ARMDAGToDAGISel::SelectShifterOperandReg(SDValue N,
SDValue &BaseReg,
SDValue &ShReg,
SDValue &Opc) {
return true;
}
-bool ARMDAGToDAGISel::SelectAddrMode2(SDNode *Op, SDValue N,
+bool ARMDAGToDAGISel::SelectAddrMode2(SDValue N,
SDValue &Base, SDValue &Offset,
SDValue &Opc) {
if (N.getOpcode() == ISD::MUL) {
}
-bool ARMDAGToDAGISel::SelectAddrMode3(SDNode *Op, SDValue N,
+bool ARMDAGToDAGISel::SelectAddrMode3(SDValue N,
SDValue &Base, SDValue &Offset,
SDValue &Opc) {
if (N.getOpcode() == ISD::SUB) {
return true;
}
-bool ARMDAGToDAGISel::SelectAddrMode4(SDNode *Op, SDValue N,
- SDValue &Addr, SDValue &Mode) {
+bool ARMDAGToDAGISel::SelectAddrMode4(SDValue N, SDValue &Addr, SDValue &Mode) {
Addr = N;
Mode = CurDAG->getTargetConstant(ARM_AM::getAM4ModeImm(ARM_AM::ia), MVT::i32);
return true;
}
-bool ARMDAGToDAGISel::SelectAddrMode5(SDNode *Op, SDValue N,
+bool ARMDAGToDAGISel::SelectAddrMode5(SDValue N,
SDValue &Base, SDValue &Offset) {
if (N.getOpcode() != ISD::ADD) {
Base = N;
return true;
}
-bool ARMDAGToDAGISel::SelectAddrMode6(SDNode *Op, SDValue N,
- SDValue &Addr, SDValue &Align) {
+bool ARMDAGToDAGISel::SelectAddrMode6(SDValue N, SDValue &Addr, SDValue &Align){
Addr = N;
// Default to no alignment.
Align = CurDAG->getTargetConstant(0, MVT::i32);
return true;
}
-bool ARMDAGToDAGISel::SelectAddrModePC(SDNode *Op, SDValue N,
+bool ARMDAGToDAGISel::SelectAddrModePC(SDValue N,
SDValue &Offset, SDValue &Label) {
if (N.getOpcode() == ARMISD::PIC_ADD && N.hasOneUse()) {
Offset = N.getOperand(0);
return false;
}
-bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDNode *Op, SDValue N,
+bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDValue N,
SDValue &Base, SDValue &Offset){
// FIXME dl should come from the parent load or store, not the address
if (N.getOpcode() != ISD::ADD) {
}
bool
-ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDNode *Op, SDValue N,
+ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDValue N,
unsigned Scale, SDValue &Base,
SDValue &OffImm, SDValue &Offset) {
if (Scale == 4) {
SDValue TmpBase, TmpOffImm;
- if (SelectThumbAddrModeSP(Op, N, TmpBase, TmpOffImm))
+ if (SelectThumbAddrModeSP(N, TmpBase, TmpOffImm))
return false; // We want to select tLDRspi / tSTRspi instead.
if (N.getOpcode() == ARMISD::Wrapper &&
N.getOperand(0).getOpcode() == ISD::TargetConstantPool)
return true;
}
-bool ARMDAGToDAGISel::SelectThumbAddrModeS1(SDNode *Op, SDValue N,
+bool ARMDAGToDAGISel::SelectThumbAddrModeS1(SDValue N,
SDValue &Base, SDValue &OffImm,
SDValue &Offset) {
- return SelectThumbAddrModeRI5(Op, N, 1, Base, OffImm, Offset);
+ return SelectThumbAddrModeRI5(N, 1, Base, OffImm, Offset);
}
-bool ARMDAGToDAGISel::SelectThumbAddrModeS2(SDNode *Op, SDValue N,
+bool ARMDAGToDAGISel::SelectThumbAddrModeS2(SDValue N,
SDValue &Base, SDValue &OffImm,
SDValue &Offset) {
- return SelectThumbAddrModeRI5(Op, N, 2, Base, OffImm, Offset);
+ return SelectThumbAddrModeRI5(N, 2, Base, OffImm, Offset);
}
-bool ARMDAGToDAGISel::SelectThumbAddrModeS4(SDNode *Op, SDValue N,
+bool ARMDAGToDAGISel::SelectThumbAddrModeS4(SDValue N,
SDValue &Base, SDValue &OffImm,
SDValue &Offset) {
- return SelectThumbAddrModeRI5(Op, N, 4, Base, OffImm, Offset);
+ return SelectThumbAddrModeRI5(N, 4, Base, OffImm, Offset);
}
-bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDNode *Op, SDValue N,
- SDValue &Base, SDValue &OffImm) {
+bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDValue N,
+ SDValue &Base, SDValue &OffImm) {
if (N.getOpcode() == ISD::FrameIndex) {
int FI = cast<FrameIndexSDNode>(N)->getIndex();
Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
return false;
}
-bool ARMDAGToDAGISel::SelectT2ShifterOperandReg(SDNode *Op, SDValue N,
- SDValue &BaseReg,
+bool ARMDAGToDAGISel::SelectT2ShifterOperandReg(SDValue N, SDValue &BaseReg,
SDValue &Opc) {
if (DisableShifterOp)
return false;
return false;
}
-bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDNode *Op, SDValue N,
+bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDValue N,
SDValue &Base, SDValue &OffImm) {
// Match simple R + imm12 operands.
}
if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
- if (SelectT2AddrModeImm8(Op, N, Base, OffImm))
+ if (SelectT2AddrModeImm8(N, Base, OffImm))
// Let t2LDRi8 handle (R - imm8).
return false;
return true;
}
-bool ARMDAGToDAGISel::SelectT2AddrModeImm8(SDNode *Op, SDValue N,
+bool ARMDAGToDAGISel::SelectT2AddrModeImm8(SDValue N,
SDValue &Base, SDValue &OffImm) {
// Match simple R - imm8 operands.
if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::SUB) {
return false;
}
-bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(SDNode *Op, SDValue N,
+bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(SDValue N,
SDValue &Base,
SDValue &OffReg, SDValue &ShImm) {
// (R - imm8) should be handled by t2LDRi8. The rest are handled by t2LDRi12.
DebugLoc dl = N->getDebugLoc();
SDValue MemAddr, Align;
- if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, Align))
+ if (!SelectAddrMode6(N->getOperand(2), MemAddr, Align))
return NULL;
SDValue Chain = N->getOperand(0);
DebugLoc dl = N->getDebugLoc();
SDValue MemAddr, Align;
- if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, Align))
+ if (!SelectAddrMode6(N->getOperand(2), MemAddr, Align))
return NULL;
SDValue Chain = N->getOperand(0);
DebugLoc dl = N->getDebugLoc();
SDValue MemAddr, Align;
- if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, Align))
+ if (!SelectAddrMode6(N->getOperand(2), MemAddr, Align))
return NULL;
SDValue Chain = N->getOperand(0);
ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag) {
SDValue CPTmp0;
SDValue CPTmp1;
- if (SelectT2ShifterOperandReg(N, TrueVal, CPTmp0, CPTmp1)) {
+ if (SelectT2ShifterOperandReg(TrueVal, CPTmp0, CPTmp1)) {
unsigned SOVal = cast<ConstantSDNode>(CPTmp1)->getZExtValue();
unsigned SOShOp = ARM_AM::getSORegShOp(SOVal);
unsigned Opc = 0;
SDValue CPTmp0;
SDValue CPTmp1;
SDValue CPTmp2;
- if (SelectShifterOperandReg(N, TrueVal, CPTmp0, CPTmp1, CPTmp2)) {
+ if (SelectShifterOperandReg(TrueVal, CPTmp0, CPTmp1, CPTmp2)) {
SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32);
SDValue Ops[] = { FalseVal, CPTmp0, CPTmp1, CPTmp2, CC, CCR, InFlag };
return CurDAG->SelectNodeTo(N, ARM::MOVCCs, MVT::i32, Ops, 7);
}
def am2offset : Operand<i32>,
- ComplexPattern<i32, 2, "SelectAddrMode2Offset", []> {
+ ComplexPattern<i32, 2, "SelectAddrMode2Offset",
+ [], [SDNPWantRoot]> {
let PrintMethod = "printAddrMode2OffsetOperand";
let MIOperandInfo = (ops GPR, i32imm);
}
}
def am3offset : Operand<i32>,
- ComplexPattern<i32, 2, "SelectAddrMode3Offset", []> {
+ ComplexPattern<i32, 2, "SelectAddrMode3Offset",
+ [], [SDNPWantRoot]> {
let PrintMethod = "printAddrMode3OffsetOperand";
let MIOperandInfo = (ops GPR, i32imm);
}
}
def t2am_imm8_offset : Operand<i32>,
- ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset", []>{
+ ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset",
+ [], [SDNPWantRoot]> {
let PrintMethod = "printT2AddrModeImm8OffsetOperand";
}
private:
SDNode *Select(SDNode *N);
- bool SelectADDRspii(SDNode *Op, SDValue Addr,
- SDValue &Base, SDValue &Offset);
+ bool SelectADDRspii(SDValue Addr, SDValue &Base, SDValue &Offset);
// Walk the DAG after instruction selection, fixing register class issues.
void FixRegisterClasses(SelectionDAG &DAG);
return SelectCode(N);
}
-bool BlackfinDAGToDAGISel::SelectADDRspii(SDNode *Op,
- SDValue Addr,
+bool BlackfinDAGToDAGISel::SelectADDRspii(SDValue Addr,
SDValue &Base,
SDValue &Offset) {
FrameIndexSDNode *FIN = 0;
// A-form : abs (256K LSA offset)
// D-form(2): [r+I7] (7-bit signed offset + reg)
-def dform_addr : ComplexPattern<iPTR, 2, "SelectDFormAddr", [], []>;
-def xform_addr : ComplexPattern<iPTR, 2, "SelectXFormAddr", [], []>;
-def aform_addr : ComplexPattern<iPTR, 2, "SelectAFormAddr", [], []>;
-def dform2_addr : ComplexPattern<iPTR, 2, "SelectDForm2Addr", [], []>;
+def dform_addr : ComplexPattern<iPTR, 2, "SelectDFormAddr",
+ [], [SDNPWantRoot]>;
+def xform_addr : ComplexPattern<iPTR, 2, "SelectXFormAddr",
+ [], [SDNPWantRoot]>;
+def aform_addr : ComplexPattern<iPTR, 2, "SelectAFormAddr",
+ [], [SDNPWantRoot]>;
+def dform2_addr : ComplexPattern<iPTR, 2, "SelectDForm2Addr",
+ [], [SDNPWantRoot]>;
SDNode *Select(SDNode *N);
// Address Selection
- bool SelectAddrRegReg(SDNode *Op, SDValue N, SDValue &Base, SDValue &Index);
- bool SelectAddrRegImm(SDNode *Op, SDValue N, SDValue &Disp, SDValue &Base);
+ bool SelectAddrRegReg(SDValue N, SDValue &Base, SDValue &Index);
+ bool SelectAddrRegImm(SDValue N, SDValue &Disp, SDValue &Base);
// getI32Imm - Return a target constant with the specified value, of type i32.
inline SDValue getI32Imm(unsigned Imm) {
/// can be represented as an indexed [r+r] operation. Returns false if it
/// can be more efficiently represented with [r+imm].
bool MBlazeDAGToDAGISel::
-SelectAddrRegReg(SDNode *Op, SDValue N, SDValue &Base, SDValue &Index) {
+SelectAddrRegReg(SDValue N, SDValue &Base, SDValue &Index) {
if (N.getOpcode() == ISD::FrameIndex) return false;
if (N.getOpcode() == ISD::TargetExternalSymbol ||
N.getOpcode() == ISD::TargetGlobalAddress)
/// a signed 32-bit displacement [r+imm], and if it is not better
/// represented as reg+reg.
bool MBlazeDAGToDAGISel::
-SelectAddrRegImm(SDNode *Op, SDValue N, SDValue &Disp, SDValue &Base) {
+SelectAddrRegImm(SDValue N, SDValue &Disp, SDValue &Base) {
// If this can be more profitably realized as r+r, fail.
- if (SelectAddrRegReg(Op, N, Disp, Base))
+ if (SelectAddrRegReg(N, Disp, Base))
return false;
if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::OR) {
SDNode *SelectIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2,
unsigned Opc8, unsigned Opc16);
- bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Disp);
+ bool SelectAddr(SDValue Addr, SDValue &Base, SDValue &Disp);
};
} // end anonymous namespace
/// SelectAddr - returns true if it is able pattern match an addressing mode.
/// It returns the operands which make up the maximal addressing mode it can
/// match by reference.
-bool MSP430DAGToDAGISel::SelectAddr(SDNode *Op, SDValue N,
+bool MSP430DAGToDAGISel::SelectAddr(SDValue N,
SDValue &Base, SDValue &Disp) {
MSP430ISelAddressMode AM;
AM.Base.Reg;
if (AM.GV)
- Disp = CurDAG->getTargetGlobalAddress(AM.GV, Op->getDebugLoc(),
+ Disp = CurDAG->getTargetGlobalAddress(AM.GV, N->getDebugLoc(),
MVT::i16, AM.Disp,
0/*AM.SymbolFlags*/);
else if (AM.CP)
switch (ConstraintCode) {
default: return true;
case 'm': // memory
- if (!SelectAddr(Op.getNode(), Op, Op0, Op1))
+ if (!SelectAddr(Op, Op0, Op1))
return true;
break;
}
SDNode *Select(SDNode *N);
// Complex Pattern.
- bool SelectAddr(SDNode *Op, SDValue N,
- SDValue &Base, SDValue &Offset);
+ bool SelectAddr(SDValue N, SDValue &Base, SDValue &Offset);
SDNode *SelectLoadFp64(SDNode *N);
SDNode *SelectStoreFp64(SDNode *N);
/// ComplexPattern used on MipsInstrInfo
/// Used on Mips Load/Store instructions
bool MipsDAGToDAGISel::
-SelectAddr(SDNode *Op, SDValue Addr, SDValue &Offset, SDValue &Base)
-{
+SelectAddr(SDValue Addr, SDValue &Offset, SDValue &Base) {
// if Address is FI, get the TargetFrameIndex.
if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
SDValue N1 = N->getOperand(1);
SDValue Offset0, Offset1, Base;
- if (!SelectAddr(N, N1, Offset0, Base) ||
+ if (!SelectAddr(N1, Offset0, Base) ||
N1.getValueType() != MVT::i32)
return NULL;
SDValue N2 = N->getOperand(2);
SDValue Offset0, Offset1, Base;
- if (!SelectAddr(N, N2, Offset0, Base) ||
+ if (!SelectAddr(N2, Offset0, Base) ||
N1.getValueType() != MVT::f64 ||
N2.getValueType() != MVT::i32)
return NULL;
// SelectDirectAddr - Match a direct address for DAG.
// A direct address could be a globaladdress or externalsymbol.
-bool PIC16DAGToDAGISel::SelectDirectAddr(SDNode *Op, SDValue N,
- SDValue &Address) {
+bool PIC16DAGToDAGISel::SelectDirectAddr(SDValue N, SDValue &Address) {
// Return true if TGA or ES.
if (N.getOpcode() == ISD::TargetGlobalAddress
|| N.getOpcode() == ISD::TargetExternalSymbol) {
SDNode *Select(SDNode *N);
// Match direct address complex pattern.
- bool SelectDirectAddr(SDNode *Op, SDValue N, SDValue &Address);
+ bool SelectDirectAddr(SDValue N, SDValue &Address);
};
/// SelectAddrImm - Returns true if the address N can be represented by
/// a base register plus a signed 16-bit displacement [r+imm].
- bool SelectAddrImm(SDNode *Op, SDValue N, SDValue &Disp,
+ bool SelectAddrImm(SDValue N, SDValue &Disp,
SDValue &Base) {
return PPCLowering.SelectAddressRegImm(N, Disp, Base, *CurDAG);
}
/// SelectAddrImmOffs - Return true if the operand is valid for a preinc
/// immediate field. Because preinc imms have already been validated, just
/// accept it.
- bool SelectAddrImmOffs(SDNode *Op, SDValue N, SDValue &Out) const {
+ bool SelectAddrImmOffs(SDValue N, SDValue &Out) const {
Out = N;
return true;
}
/// SelectAddrIdx - Given the specified addressed, check to see if it can be
/// represented as an indexed [r+r] operation. Returns false if it can
/// be represented by [r+imm], which are preferred.
- bool SelectAddrIdx(SDNode *Op, SDValue N, SDValue &Base,
- SDValue &Index) {
+ bool SelectAddrIdx(SDValue N, SDValue &Base, SDValue &Index) {
return PPCLowering.SelectAddressRegReg(N, Base, Index, *CurDAG);
}
/// SelectAddrIdxOnly - Given the specified addressed, force it to be
/// represented as an indexed [r+r] operation.
- bool SelectAddrIdxOnly(SDNode *Op, SDValue N, SDValue &Base,
- SDValue &Index) {
+ bool SelectAddrIdxOnly(SDValue N, SDValue &Base, SDValue &Index) {
return PPCLowering.SelectAddressRegRegOnly(N, Base, Index, *CurDAG);
}
/// SelectAddrImmShift - Returns true if the address N can be represented by
/// a base register plus a signed 14-bit displacement [r+imm*4]. Suitable
/// for use by STD and friends.
- bool SelectAddrImmShift(SDNode *Op, SDValue N, SDValue &Disp,
- SDValue &Base) {
+ bool SelectAddrImmShift(SDValue N, SDValue &Disp, SDValue &Base) {
return PPCLowering.SelectAddressRegImmShift(N, Disp, Base, *CurDAG);
}
SDNode *Select(SDNode *N);
// Complex Pattern Selectors.
- bool SelectADDRrr(SDNode *Op, SDValue N, SDValue &R1, SDValue &R2);
- bool SelectADDRri(SDNode *Op, SDValue N, SDValue &Base,
- SDValue &Offset);
+ bool SelectADDRrr(SDValue N, SDValue &R1, SDValue &R2);
+ bool SelectADDRri(SDValue N, SDValue &Base, SDValue &Offset);
/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
/// inline asm expressions.
return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode();
}
-bool SparcDAGToDAGISel::SelectADDRri(SDNode *Op, SDValue Addr,
+bool SparcDAGToDAGISel::SelectADDRri(SDValue Addr,
SDValue &Base, SDValue &Offset) {
if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
return true;
}
-bool SparcDAGToDAGISel::SelectADDRrr(SDNode *Op, SDValue Addr,
- SDValue &R1, SDValue &R2) {
+bool SparcDAGToDAGISel::SelectADDRrr(SDValue Addr, SDValue &R1, SDValue &R2) {
if (Addr.getOpcode() == ISD::FrameIndex) return false;
if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
Addr.getOpcode() == ISD::TargetGlobalAddress)
switch (ConstraintCode) {
default: return true;
case 'm': // memory
- if (!SelectADDRrr(Op.getNode(), Op, Op0, Op1))
- SelectADDRri(Op.getNode(), Op, Op0, Op1);
+ if (!SelectADDRrr(Op, Op0, Op1))
+ SelectADDRri(Op, Op0, Op1);
break;
}
#include "SystemZGenDAGISel.inc"
private:
- bool SelectAddrRI12Only(SDNode *Op, SDValue& Addr,
+ bool SelectAddrRI12Only(SDValue& Addr,
SDValue &Base, SDValue &Disp);
- bool SelectAddrRI12(SDNode *Op, SDValue& Addr,
+ bool SelectAddrRI12(SDValue& Addr,
SDValue &Base, SDValue &Disp,
bool is12BitOnly = false);
- bool SelectAddrRI(SDNode *Op, SDValue& Addr,
- SDValue &Base, SDValue &Disp);
- bool SelectAddrRRI12(SDNode *Op, SDValue Addr,
+ bool SelectAddrRI(SDValue& Addr, SDValue &Base, SDValue &Disp);
+ bool SelectAddrRRI12(SDValue Addr,
SDValue &Base, SDValue &Disp, SDValue &Index);
- bool SelectAddrRRI20(SDNode *Op, SDValue Addr,
+ bool SelectAddrRRI20(SDValue Addr,
SDValue &Base, SDValue &Disp, SDValue &Index);
- bool SelectLAAddr(SDNode *Op, SDValue Addr,
+ bool SelectLAAddr(SDValue Addr,
SDValue &Base, SDValue &Disp, SDValue &Index);
SDNode *Select(SDNode *Node);
/// Returns true if the address can be represented by a base register plus
/// an unsigned 12-bit displacement [r+imm].
-bool SystemZDAGToDAGISel::SelectAddrRI12Only(SDNode *Op, SDValue& Addr,
+bool SystemZDAGToDAGISel::SelectAddrRI12Only(SDValue &Addr,
SDValue &Base, SDValue &Disp) {
- return SelectAddrRI12(Op, Addr, Base, Disp, /*is12BitOnly*/true);
+ return SelectAddrRI12(Addr, Base, Disp, /*is12BitOnly*/true);
}
-bool SystemZDAGToDAGISel::SelectAddrRI12(SDNode *Op, SDValue& Addr,
+bool SystemZDAGToDAGISel::SelectAddrRI12(SDValue &Addr,
SDValue &Base, SDValue &Disp,
bool is12BitOnly) {
SystemZRRIAddressMode AM20(/*isRI*/true), AM12(/*isRI*/true);
/// Returns true if the address can be represented by a base register plus
/// a signed 20-bit displacement [r+imm].
-bool SystemZDAGToDAGISel::SelectAddrRI(SDNode *Op, SDValue& Addr,
+bool SystemZDAGToDAGISel::SelectAddrRI(SDValue& Addr,
SDValue &Base, SDValue &Disp) {
SystemZRRIAddressMode AM(/*isRI*/true);
bool Done = false;
/// Returns true if the address can be represented by a base register plus
/// index register plus an unsigned 12-bit displacement [base + idx + imm].
-bool SystemZDAGToDAGISel::SelectAddrRRI12(SDNode *Op, SDValue Addr,
+bool SystemZDAGToDAGISel::SelectAddrRRI12(SDValue Addr,
SDValue &Base, SDValue &Disp, SDValue &Index) {
SystemZRRIAddressMode AM20, AM12;
bool Done = false;
/// Returns true if the address can be represented by a base register plus
/// index register plus a signed 20-bit displacement [base + idx + imm].
-bool SystemZDAGToDAGISel::SelectAddrRRI20(SDNode *Op, SDValue Addr,
+bool SystemZDAGToDAGISel::SelectAddrRRI20(SDValue Addr,
SDValue &Base, SDValue &Disp, SDValue &Index) {
SystemZRRIAddressMode AM;
bool Done = false;
/// SelectLAAddr - it calls SelectAddr and determines if the maximal addressing
/// mode it matches can be cost effectively emitted as an LA/LAY instruction.
-bool SystemZDAGToDAGISel::SelectLAAddr(SDNode *Op, SDValue Addr,
+bool SystemZDAGToDAGISel::SelectLAAddr(SDValue Addr,
SDValue &Base, SDValue &Disp, SDValue &Index) {
SystemZRRIAddressMode AM;
SDValue &Base, SDValue &Disp, SDValue &Index) {
if (ISD::isNON_EXTLoad(N.getNode()) &&
IsLegalToFold(N, P, P, OptLevel))
- return SelectAddrRRI20(P, N.getOperand(1), Base, Disp, Index);
+ return SelectAddrRRI20(N.getOperand(1), Base, Disp, Index);
return false;
}
bool MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM,
unsigned Depth);
bool MatchAddressBase(SDValue N, X86ISelAddressMode &AM);
- bool SelectAddr(SDNode *Op, SDValue N, SDValue &Base,
+ bool SelectAddr(SDValue N, SDValue &Base,
SDValue &Scale, SDValue &Index, SDValue &Disp,
SDValue &Segment);
- bool SelectLEAAddr(SDNode *Op, SDValue N, SDValue &Base,
+ bool SelectLEAAddr(SDValue N, SDValue &Base,
SDValue &Scale, SDValue &Index, SDValue &Disp,
SDValue &Segment);
- bool SelectTLSADDRAddr(SDNode *Op, SDValue N, SDValue &Base,
+ bool SelectTLSADDRAddr(SDValue N, SDValue &Base,
SDValue &Scale, SDValue &Index, SDValue &Disp,
SDValue &Segment);
bool SelectScalarSSELoad(SDNode *Root, SDValue N,
/// SelectAddr - returns true if it is able pattern match an addressing mode.
/// It returns the operands which make up the maximal addressing mode it can
/// match by reference.
-bool X86DAGToDAGISel::SelectAddr(SDNode *Op, SDValue N, SDValue &Base,
+bool X86DAGToDAGISel::SelectAddr(SDValue N, SDValue &Base,
SDValue &Scale, SDValue &Index,
SDValue &Disp, SDValue &Segment) {
X86ISelAddressMode AM;
IsProfitableToFold(N.getOperand(0), N.getNode(), Root) &&
IsLegalToFold(N.getOperand(0), N.getNode(), Root, OptLevel)) {
LoadSDNode *LD = cast<LoadSDNode>(PatternNodeWithChain);
- if (!SelectAddr(Root, LD->getBasePtr(), Base, Scale, Index, Disp,Segment))
+ if (!SelectAddr(LD->getBasePtr(), Base, Scale, Index, Disp,Segment))
return false;
return true;
}
IsLegalToFold(N.getOperand(0), N.getNode(), Root, OptLevel)) {
// Okay, this is a zero extending load. Fold it.
LoadSDNode *LD = cast<LoadSDNode>(N.getOperand(0).getOperand(0));
- if (!SelectAddr(Root, LD->getBasePtr(), Base, Scale, Index, Disp, Segment))
+ if (!SelectAddr(LD->getBasePtr(), Base, Scale, Index, Disp, Segment))
return false;
PatternNodeWithChain = SDValue(LD, 0);
return true;
/// SelectLEAAddr - it calls SelectAddr and determines if the maximal addressing
/// mode it matches can be cost effectively emitted as an LEA instruction.
-bool X86DAGToDAGISel::SelectLEAAddr(SDNode *Op, SDValue N,
+bool X86DAGToDAGISel::SelectLEAAddr(SDValue N,
SDValue &Base, SDValue &Scale,
SDValue &Index, SDValue &Disp,
SDValue &Segment) {
}
/// SelectTLSADDRAddr - This is only run on TargetGlobalTLSAddress nodes.
-bool X86DAGToDAGISel::SelectTLSADDRAddr(SDNode *Op, SDValue N, SDValue &Base,
+bool X86DAGToDAGISel::SelectTLSADDRAddr(SDValue N, SDValue &Base,
SDValue &Scale, SDValue &Index,
SDValue &Disp, SDValue &Segment) {
assert(N.getOpcode() == ISD::TargetGlobalTLSAddress);
!IsLegalToFold(N, P, P, OptLevel))
return false;
- return SelectAddr(P, N.getOperand(1), Base, Scale, Index, Disp, Segment);
+ return SelectAddr(N.getOperand(1), Base, Scale, Index, Disp, Segment);
}
/// getGlobalBaseReg - Return an SDNode that returns the value of
SDValue In2L = Node->getOperand(2);
SDValue In2H = Node->getOperand(3);
SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
- if (!SelectAddr(In1.getNode(), In1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4))
+ if (!SelectAddr(In1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4))
return NULL;
MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
MemOp[0] = cast<MemSDNode>(Node)->getMemOperand();
SDValue Ptr = Node->getOperand(1);
SDValue Val = Node->getOperand(2);
SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
- if (!SelectAddr(Ptr.getNode(), Ptr, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4))
+ if (!SelectAddr(Ptr, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4))
return 0;
bool isInc = false, isDec = false, isSub = false, isCN = false;
case 'v': // not offsetable ??
default: return true;
case 'm': // memory
- if (!SelectAddr(Op.getNode(), Op, Op0, Op1, Op2, Op3, Op4))
+ if (!SelectAddr(Op, Op0, Op1, Op2, Op3, Op4))
return true;
break;
}
// the top elements. These are used for the SSE 'ss' and 'sd' instruction
// forms.
def sse_load_f32 : ComplexPattern<v4f32, 5, "SelectScalarSSELoad", [],
- [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
+ [SDNPHasChain, SDNPMayLoad, SDNPMemOperand,
+ SDNPWantRoot]>;
def sse_load_f64 : ComplexPattern<v2f64, 5, "SelectScalarSSELoad", [],
- [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
+ [SDNPHasChain, SDNPMayLoad, SDNPMemOperand,
+ SDNPWantRoot]>;
def ssmem : Operand<v4f32> {
let PrintMethod = "printf32mem";
}
// Complex Pattern Selectors.
- bool SelectADDRspii(SDNode *Op, SDValue Addr, SDValue &Base,
- SDValue &Offset);
- bool SelectADDRdpii(SDNode *Op, SDValue Addr, SDValue &Base,
- SDValue &Offset);
- bool SelectADDRcpii(SDNode *Op, SDValue Addr, SDValue &Base,
- SDValue &Offset);
+ bool SelectADDRspii(SDValue Addr, SDValue &Base, SDValue &Offset);
+ bool SelectADDRdpii(SDValue Addr, SDValue &Base, SDValue &Offset);
+ bool SelectADDRcpii(SDValue Addr, SDValue &Base, SDValue &Offset);
virtual const char *getPassName() const {
return "XCore DAG->DAG Pattern Instruction Selection";
return new XCoreDAGToDAGISel(TM);
}
-bool XCoreDAGToDAGISel::SelectADDRspii(SDNode *Op, SDValue Addr,
- SDValue &Base, SDValue &Offset) {
+bool XCoreDAGToDAGISel::SelectADDRspii(SDValue Addr, SDValue &Base,
+ SDValue &Offset) {
FrameIndexSDNode *FIN = 0;
if ((FIN = dyn_cast<FrameIndexSDNode>(Addr))) {
Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
return false;
}
-bool XCoreDAGToDAGISel::SelectADDRdpii(SDNode *Op, SDValue Addr,
- SDValue &Base, SDValue &Offset) {
+bool XCoreDAGToDAGISel::SelectADDRdpii(SDValue Addr, SDValue &Base,
+ SDValue &Offset) {
if (Addr.getOpcode() == XCoreISD::DPRelativeWrapper) {
Base = Addr.getOperand(0);
Offset = CurDAG->getTargetConstant(0, MVT::i32);
return false;
}
-bool XCoreDAGToDAGISel::SelectADDRcpii(SDNode *Op, SDValue Addr,
- SDValue &Base, SDValue &Offset) {
+bool XCoreDAGToDAGISel::SelectADDRcpii(SDValue Addr, SDValue &Base,
+ SDValue &Offset) {
if (Addr.getOpcode() == XCoreISD::CPRelativeWrapper) {
Base = Addr.getOperand(0);
Offset = CurDAG->getTargetConstant(0, MVT::i32);
Properties |= 1 << SDNPMemOperand;
} else if (PropList[i]->getName() == "SDNPVariadic") {
Properties |= 1 << SDNPVariadic;
+ } else if (PropList[i]->getName() == "SDNPWantRoot") {
+ Properties |= 1 << SDNPWantRoot;
+ } else if (PropList[i]->getName() == "SDNPWantParent") {
+ Properties |= 1 << SDNPWantParent;
} else {
errs() << "Unsupported SD Node property '" << PropList[i]->getName()
<< "' on ComplexPattern '" << R->getName() << "'!\n";
SDNPMayStore,
SDNPSideEffect,
SDNPMemOperand,
- SDNPVariadic
+ SDNPVariadic,
+ SDNPWantRoot,
+ SDNPWantParent
};
/// getValueType - Return the MVT::SimpleValueType that the specified TableGen
OS << " Result.resize(NextRes+" << NumOps << ");\n";
OS << " return " << P.getSelectFunc();
- OS << "(Root, N";
+ OS << "(";
+ // If the complex pattern wants the root of the match, pass it in as the
+ // first argument.
+ if (P.hasProperty(SDNPWantRoot))
+ OS << "Root, ";
+
+ OS << "N";
for (unsigned i = 0; i != NumOps; ++i)
OS << ", Result[NextRes+" << i << ']';
OS << ");\n";