24 struct SystemZAddressingMode {
59 bool IncludesDynAlloc;
61 SystemZAddressingMode(AddrForm form, DispRange dr)
62 : Form(form), DR(dr), Base(), Disp(0), Index(),
63 IncludesDynAlloc(
false) {}
66 bool hasIndexField() {
return Form != FormBD; }
69 bool isDynAlloc() {
return Form == FormBDXDynAlloc; }
72 errs() <<
"SystemZAddressingMode " <<
this <<
'\n';
75 if (Base.getNode() != 0)
76 Base.getNode()->dump();
80 if (hasIndexField()) {
82 if (Index.getNode() != 0)
83 Index.getNode()->dump();
88 errs() <<
" Disp " << Disp;
90 errs() <<
" + ADJDYNALLOC";
96 static uint64_t
allOnes(
unsigned int Count) {
97 return Count == 0 ? 0 : (uint64_t(1) << (Count - 1) << 1) - 1;
112 struct RxSBGOperands {
113 RxSBGOperands(
unsigned Op,
SDValue N)
114 : Opcode(Op), BitSize(N.getValueType().getSizeInBits()),
115 Mask(
allOnes(BitSize)), Input(N), Start(64 - BitSize), End(63),
132 inline SDValue getImm(
const SDNode *Node, uint64_t Imm)
const {
133 return CurDAG->getTargetConstant(Imm, Node->
getValueType(0));
141 return getTargetMachine().getInstrInfo();
146 bool expandAddress(SystemZAddressingMode &AM,
bool IsBase)
const;
149 bool selectAddress(
SDValue N, SystemZAddressingMode &AM)
const;
152 void getAddressOperands(
const SystemZAddressingMode &AM,
EVT VT,
154 void getAddressOperands(
const SystemZAddressingMode &AM,
EVT VT,
160 bool selectBDAddr(SystemZAddressingMode::DispRange DR,
SDValue Addr,
166 bool selectMVIAddr(SystemZAddressingMode::DispRange DR,
SDValue Addr,
172 bool selectBDXAddr(SystemZAddressingMode::AddrForm Form,
173 SystemZAddressingMode::DispRange DR,
SDValue Addr,
187 return selectBDAddr(SystemZAddressingMode::Disp12Only, Addr, Base, Disp);
190 return selectBDAddr(SystemZAddressingMode::Disp12Pair, Addr, Base, Disp);
193 return selectBDAddr(SystemZAddressingMode::Disp20Only, Addr, Base, Disp);
196 return selectBDAddr(SystemZAddressingMode::Disp20Pair, Addr, Base, Disp);
201 return selectMVIAddr(SystemZAddressingMode::Disp12Pair, Addr, Base, Disp);
204 return selectMVIAddr(SystemZAddressingMode::Disp20Pair, Addr, Base, Disp);
210 return selectBDXAddr(SystemZAddressingMode::FormBDXNormal,
211 SystemZAddressingMode::Disp12Only,
212 Addr, Base, Disp, Index);
216 return selectBDXAddr(SystemZAddressingMode::FormBDXNormal,
217 SystemZAddressingMode::Disp12Pair,
218 Addr, Base, Disp, Index);
222 return selectBDXAddr(SystemZAddressingMode::FormBDXDynAlloc,
223 SystemZAddressingMode::Disp12Only,
224 Addr, Base, Disp, Index);
228 return selectBDXAddr(SystemZAddressingMode::FormBDXNormal,
229 SystemZAddressingMode::Disp20Only,
230 Addr, Base, Disp, Index);
234 return selectBDXAddr(SystemZAddressingMode::FormBDXNormal,
235 SystemZAddressingMode::Disp20Only128,
236 Addr, Base, Disp, Index);
240 return selectBDXAddr(SystemZAddressingMode::FormBDXNormal,
241 SystemZAddressingMode::Disp20Pair,
242 Addr, Base, Disp, Index);
246 return selectBDXAddr(SystemZAddressingMode::FormBDXLA,
247 SystemZAddressingMode::Disp12Pair,
248 Addr, Base, Disp, Index);
252 return selectBDXAddr(SystemZAddressingMode::FormBDXLA,
253 SystemZAddressingMode::Disp20Pair,
254 Addr, Base, Disp, Index);
260 bool detectOrAndInsertion(
SDValue &Op, uint64_t InsertMask)
const;
264 bool refineRxSBGMask(RxSBGOperands &RxSBG, uint64_t Mask)
const;
268 bool expandRxSBG(RxSBGOperands &RxSBG)
const;
292 uint64_t UpperVal, uint64_t LowerVal);
307 bool storeLoadCanUseMVC(
SDNode *
N)
const;
312 bool storeLoadCanUseBlockBinary(
SDNode *
N,
unsigned I)
const;
317 Lowering(*TM.getTargetLowering()),
318 Subtarget(*TM.getSubtargetImpl()) { }
322 return "SystemZ DAG->DAG Pattern Instruction Selection";
327 virtual bool SelectInlineAsmMemoryOperand(
const SDValue &Op,
329 std::vector<SDValue> &OutOps)
333 #include "SystemZGenDAGISel.inc"
339 return new SystemZDAGToDAGISel(TM, OptLevel);
345 static bool selectDisp(SystemZAddressingMode::DispRange DR, int64_t Val) {
347 case SystemZAddressingMode::Disp12Only:
348 return isUInt<12>(Val);
350 case SystemZAddressingMode::Disp12Pair:
351 case SystemZAddressingMode::Disp20Only:
352 case SystemZAddressingMode::Disp20Pair:
353 return isInt<20>(Val);
355 case SystemZAddressingMode::Disp20Only128:
356 return isInt<20>(Val) && isInt<20>(Val + 8);
376 if (AM.isDynAlloc() && !AM.IncludesDynAlloc) {
378 AM.IncludesDynAlloc =
true;
388 if (AM.hasIndexField() && !AM.Index.getNode()) {
398 static bool expandDisp(SystemZAddressingMode &AM,
bool IsBase,
401 int64_t TestDisp = AM.Disp + Op1;
413 bool SystemZDAGToDAGISel::expandAddress(SystemZAddressingMode &AM,
415 SDValue N = IsBase ? AM.Base : AM.Index;
421 if (Opcode ==
ISD::ADD || CurDAG->isBaseWithConstantOffset(N)) {
435 cast<ConstantSDNode>(Op0)->getSExtValue());
438 cast<ConstantSDNode>(Op1)->getSExtValue());
447 uint64_t Offset = (cast<GlobalAddressSDNode>(Full)->getOffset() -
448 cast<GlobalAddressSDNode>(Anchor)->getOffset());
456 static bool isValidDisp(SystemZAddressingMode::DispRange DR, int64_t Val) {
457 assert(
selectDisp(DR, Val) &&
"Invalid displacement");
459 case SystemZAddressingMode::Disp12Only:
460 case SystemZAddressingMode::Disp20Only:
461 case SystemZAddressingMode::Disp20Only128:
464 case SystemZAddressingMode::Disp12Pair:
466 return isUInt<12>(Val);
468 case SystemZAddressingMode::Disp20Pair:
470 return !isUInt<12>(Val);
494 if (isUInt<12>(Disp))
513 unsigned IndexOpcode = Index->
getOpcode();
528 bool SystemZDAGToDAGISel::selectAddress(
SDValue Addr,
529 SystemZAddressingMode &AM)
const {
537 cast<ConstantSDNode>(Addr)->getSExtValue()))
541 while (expandAddress(AM,
true) ||
542 (AM.Index.getNode() && expandAddress(AM,
false)))
546 if (AM.Form == SystemZAddressingMode::FormBDXLA &&
547 !
shouldUseLA(AM.Base.getNode(), AM.Disp, AM.Index.getNode()))
555 if (AM.isDynAlloc() && !AM.IncludesDynAlloc)
575 void SystemZDAGToDAGISel::getAddressOperands(
const SystemZAddressingMode &AM,
581 Base = CurDAG->getRegister(0, VT);
584 int64_t
FrameIndex = cast<FrameIndexSDNode>(Base)->getIndex();
585 Base = CurDAG->getTargetFrameIndex(FrameIndex, VT);
589 "Unexpected truncation");
597 Disp = CurDAG->getTargetConstant(AM.Disp, VT);
600 void SystemZDAGToDAGISel::getAddressOperands(
const SystemZAddressingMode &AM,
604 getAddressOperands(AM, VT, Base, Disp);
609 Index = CurDAG->getRegister(0, VT);
612 bool SystemZDAGToDAGISel::selectBDAddr(SystemZAddressingMode::DispRange DR,
615 SystemZAddressingMode AM(SystemZAddressingMode::FormBD, DR);
616 if (!selectAddress(Addr, AM))
619 getAddressOperands(AM, Addr.
getValueType(), Base, Disp);
623 bool SystemZDAGToDAGISel::selectMVIAddr(SystemZAddressingMode::DispRange DR,
626 SystemZAddressingMode AM(SystemZAddressingMode::FormBDXNormal, DR);
627 if (!selectAddress(Addr, AM) || AM.Index.getNode())
630 getAddressOperands(AM, Addr.
getValueType(), Base, Disp);
634 bool SystemZDAGToDAGISel::selectBDXAddr(SystemZAddressingMode::AddrForm Form,
635 SystemZAddressingMode::DispRange DR,
638 SystemZAddressingMode AM(Form, DR);
639 if (!selectAddress(Addr, AM))
642 getAddressOperands(AM, Addr.
getValueType(), Base, Disp, Index);
646 bool SystemZDAGToDAGISel::detectOrAndInsertion(
SDValue &Op,
647 uint64_t InsertMask)
const {
661 if (InsertMask & AndMask)
667 if (Used != (AndMask | InsertMask)) {
668 APInt KnownZero, KnownOne;
669 CurDAG->ComputeMaskedBits(Op.
getOperand(0), KnownZero, KnownOne);
670 if (Used != (AndMask | InsertMask | KnownZero.
getZExtValue()))
678 bool SystemZDAGToDAGISel::refineRxSBGMask(RxSBGOperands &RxSBG,
679 uint64_t Mask)
const {
681 if (RxSBG.Rotate != 0)
682 Mask = (Mask << RxSBG.Rotate) | (Mask >> (64 - RxSBG.Rotate));
684 if (TII->
isRxSBGMask(Mask, RxSBG.BitSize, RxSBG.Start, RxSBG.End)) {
694 if (RxSBG.Rotate != 0)
695 Mask = ((Mask << RxSBG.Rotate) | (Mask >> (64 - RxSBG.Rotate)));
696 return (Mask & RxSBG.Mask) != 0;
699 bool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG)
const {
704 if (RxSBG.Opcode == SystemZ::RNSBG)
714 if (!refineRxSBGMask(RxSBG, Mask)) {
718 APInt KnownZero, KnownOne;
719 CurDAG->ComputeMaskedBits(Input, KnownZero, KnownOne);
721 if (!refineRxSBGMask(RxSBG, Mask))
729 if (RxSBG.Opcode != SystemZ::RNSBG)
739 if (!refineRxSBGMask(RxSBG, Mask)) {
743 APInt KnownZero, KnownOne;
744 CurDAG->ComputeMaskedBits(Input, KnownZero, KnownOne);
746 if (!refineRxSBGMask(RxSBG, Mask))
762 RxSBG.Rotate = (RxSBG.Rotate + CountNode->
getZExtValue()) & 63;
788 if (Count < 1 || Count >= BitSize)
791 if (RxSBG.Opcode == SystemZ::RNSBG) {
798 if (!refineRxSBGMask(RxSBG,
allOnes(BitSize - Count) << Count))
802 RxSBG.Rotate = (RxSBG.Rotate + Count) & 63;
816 if (Count < 1 || Count >= BitSize)
819 if (RxSBG.Opcode == SystemZ::RNSBG || Opcode ==
ISD::SRA) {
827 if (!refineRxSBGMask(RxSBG,
allOnes(BitSize - Count)))
831 RxSBG.Rotate = (RxSBG.Rotate - Count) & 63;
847 return CurDAG->getTargetInsertSubreg(SystemZ::subreg_l32,
850 return CurDAG->getTargetExtractSubreg(SystemZ::subreg_l32, DL, VT, N);
851 assert(N.
getValueType() == VT &&
"Unexpected value types");
857 RxSBGOperands RISBG(SystemZ::RISBG,
SDValue(N, 0));
859 while (expandRxSBG(RISBG))
874 RISBG.Mask == 0xff ||
875 RISBG.Mask == 0xffff ||
881 SDValue NewMask = CurDAG->getConstant(RISBG.Mask, VT);
882 N = CurDAG->UpdateNodeOperands(N, N->
getOperand(0), NewMask);
883 return SelectCode(N);
889 unsigned Opcode = SystemZ::RISBG;
891 if (VT ==
MVT::i32 && Subtarget.hasHighWord()) {
892 Opcode = SystemZ::RISBMux;
898 getUNDEF(
SDLoc(N), OpcodeVT),
899 convertTo(
SDLoc(N), OpcodeVT, RISBG.Input),
900 CurDAG->getTargetConstant(RISBG.Start,
MVT::i32),
901 CurDAG->getTargetConstant(RISBG.End | 128,
MVT::i32),
902 CurDAG->getTargetConstant(RISBG.Rotate,
MVT::i32)
904 N = CurDAG->getMachineNode(Opcode,
SDLoc(N), OpcodeVT, Ops);
905 return convertTo(
SDLoc(N), VT,
SDValue(N, 0)).getNode();
908 SDNode *SystemZDAGToDAGISel::tryRxSBG(
SDNode *N,
unsigned Opcode) {
911 RxSBGOperands RxSBG[] = {
915 unsigned Count[] = { 0, 0 };
916 for (
unsigned I = 0;
I < 2; ++
I)
917 while (expandRxSBG(RxSBG[
I]))
922 if (Count[0] == 0 && Count[1] == 0)
926 unsigned I = Count[0] > Count[1] ? 0 : 1;
930 if (Opcode == SystemZ::ROSBG && (RxSBG[I].Mask & 0xff) == 0)
937 if (Opcode == SystemZ::ROSBG && detectOrAndInsertion(Op0, RxSBG[I].Mask))
938 Opcode = SystemZ::RISBG;
944 CurDAG->getTargetConstant(RxSBG[I].Start,
MVT::i32),
945 CurDAG->getTargetConstant(RxSBG[I].End,
MVT::i32),
946 CurDAG->getTargetConstant(RxSBG[I].Rotate,
MVT::i32)
949 return convertTo(
SDLoc(N), VT,
SDValue(N, 0)).getNode();
952 SDNode *SystemZDAGToDAGISel::splitLargeImmediate(
unsigned Opcode,
SDNode *Node,
953 SDValue Op0, uint64_t UpperVal,
957 SDValue Upper = CurDAG->getConstant(UpperVal, VT);
959 Upper = CurDAG->getNode(Opcode, DL, VT, Op0, Upper);
962 SDValue Lower = CurDAG->getConstant(LowerVal, VT);
963 SDValue Or = CurDAG->getNode(Opcode, DL, VT, Upper, Lower);
991 if (V1 == V2 && End1 == End2)
998 bool SystemZDAGToDAGISel::storeLoadCanUseMVC(
SDNode *N)
const {
1005 if (Size > 1 && Size <= 8) {
1014 return canUseBlockOperation(Store, Load);
1017 bool SystemZDAGToDAGISel::storeLoadCanUseBlockBinary(
SDNode *N,
1022 return !LoadA->
isVolatile() && canUseBlockOperation(StoreA, LoadB);
1041 ResNode = tryRxSBG(Node, SystemZ::ROSBG);
1046 ResNode = tryRxSBG(Node, SystemZ::RXSBG);
1053 uint64_t Val = Op1->getZExtValue();
1055 Node = splitLargeImmediate(Opcode, Node, Node->
getOperand(0),
1056 Val - uint32_t(Val), uint32_t(Val));
1062 ResNode = tryRxSBG(Node, SystemZ::RNSBG);
1068 ResNode = tryRISBGZero(Node);
1075 uint64_t Val = cast<ConstantSDNode>(Node)->getZExtValue();
1078 Val - uint32_t(Val), uint32_t(Val));
1085 uint64_t
Value = -Op2->getZExtValue();
1089 CurDAG->getConstant(int32_t(Value), VT) };
1104 uint64_t ConstCCValid =
1105 cast<ConstantSDNode>(CCValid.
getNode())->getZExtValue();
1106 uint64_t ConstCCMask =
1107 cast<ConstantSDNode>(CCMask.
getNode())->getZExtValue();
1109 CCMask = CurDAG->getConstant(ConstCCValid ^ ConstCCMask,
1112 Node = CurDAG->UpdateNodeOperands(Node, Op1, Op0, CCValid, CCMask, Op4);
1120 ResNode = SelectCode(Node);
1123 if (ResNode == NULL || ResNode == Node)
1126 ResNode->
dump(CurDAG);
1132 bool SystemZDAGToDAGISel::
1133 SelectInlineAsmMemoryOperand(
const SDValue &Op,
1134 char ConstraintCode,
1135 std::vector<SDValue> &OutOps) {
1136 assert(ConstraintCode ==
'm' &&
"Unexpected constraint code");
1140 if (!selectBDXAddr(SystemZAddressingMode::FormBD,
1141 SystemZAddressingMode::Disp12Only,
1142 Op, Base, Disp, Index))
1144 OutOps.push_back(Base);
1145 OutOps.push_back(Disp);
1146 OutOps.push_back(Index);
bool isInt< 32 >(int64_t x)
static bool isImmHF(uint64_t Val)
static void insertDAGNode(SelectionDAG *DAG, SDNode *Pos, SDValue N)
uint64_t getZExtValue() const
Get zero extended value.
void dump() const
dump - Dump this node, for debugging.
SDVTList getVTList() const
static bool isImmLF(uint64_t Val)
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
static bool maskMatters(RxSBGOperands &RxSBG, uint64_t Mask)
unsigned getOpcode() const
const SDValue & getOperand(unsigned Num) const
void setNodeId(int Id)
setNodeId - Set unique node id.
int64_t getSrcValueOffset() const
static uint64_t allOnes(unsigned int Count)
const HexagonInstrInfo * TII
#define llvm_unreachable(msg)
EVT getValueType(unsigned ResNo) const
FunctionPass * createSystemZISelDag(SystemZTargetMachine &TM, CodeGenOpt::Level OptLevel)
size_t array_lengthof(T(&)[N])
Find the length of an array.
Simple integer binary arithmetic operators.
static bool expandAdjDynAlloc(SystemZAddressingMode &AM, bool IsBase, SDValue Value)
const SDValue & getBasePtr() const
EVT getMemoryVT() const
getMemoryVT - Return the type of the in-memory value.
static bool shouldUseLA(SDNode *Base, int64_t Disp, SDNode *Index)
SDNode * getNode() const
get the SDNode which holds the desired result
unsigned getStoreSize() const
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
const SDValue & getOperand(unsigned i) const
static bool expandDisp(SystemZAddressingMode &AM, bool IsBase, SDValue Op0, uint64_t Op1)
APInt Or(const APInt &LHS, const APInt &RHS)
Bitwise OR function for APInt.
void RepositionNode(allnodes_iterator Position, SDNode *N)
static void changeComponent(SystemZAddressingMode &AM, bool IsBase, SDValue Value)
unsigned getOpcode() const
bool isPCREL(unsigned Opcode)
const SDValue & getValue() const
Location - A description of a memory location.
bool isRxSBGMask(uint64_t Mask, unsigned BitSize, unsigned &Start, unsigned &End) const
const MDNode * getTBAAInfo() const
Returns the TBAAInfo that describes the dereference.
Class for arbitrary precision integers.
ZERO_EXTEND - Used for integer types, zeroing the new bits.
ANY_EXTEND - Used for integer types. The high bits are undefined.
Bitwise operators - logical and, logical or, logical xor.
IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
unsigned getSizeInBits() const
getSizeInBits - Return the size of the specified value type in bits.
const Value * getSrcValue() const
Returns the SrcValue and offset that describes the location of the access.
bool isInt< 16 >(int64_t x)
static bool selectDisp(SystemZAddressingMode::DispRange DR, int64_t Val)
static bool expandIndex(SystemZAddressingMode &AM, SDValue Base, SDValue Index)
LLVM Value Representation.
static bool isValidDisp(SystemZAddressingMode::DispRange DR, int64_t Val)
TRUNCATE - Completely drop the high bits.
bool isMachineOpcode() const
uint64_t getZExtValue() const