11d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===-- SystemZISelDAGToDAG.cpp - A dag to dag inst selector for SystemZ --===// 21d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 31d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// The LLVM Compiler Infrastructure 41d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 51d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// This file is distributed under the University of Illinois Open Source 61d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// License. See LICENSE.TXT for details. 71d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 81d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===// 91d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// This file defines an instruction selector for the SystemZ target. 111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===// 131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZTargetMachine.h" 152e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford#include "llvm/Analysis/AliasAnalysis.h" 161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "llvm/CodeGen/SelectionDAGISel.h" 171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "llvm/Support/Debug.h" 181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "llvm/Support/raw_ostream.h" 191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandusing namespace llvm; 211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 22dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "systemz-isel" 23dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandnamespace { 251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Used to build addressing modes. 261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstruct SystemZAddressingMode { 271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // The shape of the address. 281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand enum AddrForm { 291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // base+displacement 301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FormBD, 311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // base+displacement+index for load and store operands 331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FormBDXNormal, 341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // base+displacement+index for load address operands 361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FormBDXLA, 371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // base+displacement+index+ADJDYNALLOC 391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FormBDXDynAlloc 401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand }; 411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand AddrForm Form; 421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // The type of displacement. The enum names here correspond directly 441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // to the definitions in SystemZOperand.td. We could split them into 451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // flags -- single/pair, 128-bit, etc. -- but it hardly seems worth it. 461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand enum DispRange { 471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Disp12Only, 481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Disp12Pair, 491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Disp20Only, 501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Disp20Only128, 511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Disp20Pair 521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand }; 531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DispRange DR; 541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // The parts of the address. The address is equivalent to: 561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // 571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Base + Disp + Index + (IncludesDynAlloc ? ADJDYNALLOC : 0) 581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Base; 591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t Disp; 601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Index; 611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool IncludesDynAlloc; 621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode(AddrForm form, DispRange dr) 641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand : Form(form), DR(dr), Base(), Disp(0), Index(), 651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand IncludesDynAlloc(false) {} 661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // True if the address can have an index register. 681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool hasIndexField() { return Form != FormBD; } 691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // True if the address can (and must) include ADJDYNALLOC. 711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool isDynAlloc() { return Form == FormBDXDynAlloc; } 721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand void dump() { 741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand errs() << "SystemZAddressingMode " << this << '\n'; 751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand errs() << " Base "; 77dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Base.getNode()) 781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Base.getNode()->dump(); 791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand errs() << "null\n"; 811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (hasIndexField()) { 831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand errs() << " Index "; 84dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Index.getNode()) 851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Index.getNode()->dump(); 861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand errs() << "null\n"; 881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand errs() << " Disp " << Disp; 911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IncludesDynAlloc) 921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand errs() << " + ADJDYNALLOC"; 931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand errs() << '\n'; 941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand}; 961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 97376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford// Return a mask with Count low bits set. 98376452165863fad987c890d9773e6eb87742a3e1Richard Sandifordstatic uint64_t allOnes(unsigned int Count) { 99376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return Count == 0 ? 0 : (uint64_t(1) << (Count - 1) << 1) - 1; 100376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford} 101376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 102722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford// Represents operands 2 to 5 of the ROTATE AND ... SELECTED BITS operation 103722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford// given by Opcode. The operands are: Input (R2), Start (I3), End (I4) and 104722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford// Rotate (I5). The combined operand value is effectively: 105722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford// 106722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford// (or (rotl Input, Rotate), ~Mask) 107722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford// 108722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford// for RNSBG and: 109722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford// 110722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford// (and (rotl Input, Rotate), Mask) 111722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford// 112d77a7669ec1a6bba7e45791b1aa1e65a603dda92Richard Sandiford// otherwise. The output value has BitSize bits, although Input may be 113d77a7669ec1a6bba7e45791b1aa1e65a603dda92Richard Sandiford// narrower (in which case the upper bits are don't care). 114efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandifordstruct RxSBGOperands { 115722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford RxSBGOperands(unsigned Op, SDValue N) 116722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford : Opcode(Op), BitSize(N.getValueType().getSizeInBits()), 117722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford Mask(allOnes(BitSize)), Input(N), Start(64 - BitSize), End(63), 118722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford Rotate(0) {} 119376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 120722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford unsigned Opcode; 121376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford unsigned BitSize; 122376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford uint64_t Mask; 123376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford SDValue Input; 124376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford unsigned Start; 125376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford unsigned End; 126376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford unsigned Rotate; 127376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford}; 128376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 1291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandclass SystemZDAGToDAGISel : public SelectionDAGISel { 1301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SystemZTargetLowering &Lowering; 1311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SystemZSubtarget &Subtarget; 1321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Used by SystemZOperands.td to create integer constants. 1348dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford inline SDValue getImm(const SDNode *Node, uint64_t Imm) const { 1351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return CurDAG->getTargetConstant(Imm, Node->getValueType(0)); 1361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 138b3f912b510f8040690864126351b7021980558bbRichard Sandiford const SystemZTargetMachine &getTargetMachine() const { 139b3f912b510f8040690864126351b7021980558bbRichard Sandiford return static_cast<const SystemZTargetMachine &>(TM); 140b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 141b3f912b510f8040690864126351b7021980558bbRichard Sandiford 142b3f912b510f8040690864126351b7021980558bbRichard Sandiford const SystemZInstrInfo *getInstrInfo() const { 143b3f912b510f8040690864126351b7021980558bbRichard Sandiford return getTargetMachine().getInstrInfo(); 144b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 145b3f912b510f8040690864126351b7021980558bbRichard Sandiford 1461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Try to fold more of the base or index of AM into AM, where IsBase 1471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // selects between the base and index. 1488dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool expandAddress(SystemZAddressingMode &AM, bool IsBase) const; 1491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Try to describe N in AM, returning true on success. 1518dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool selectAddress(SDValue N, SystemZAddressingMode &AM) const; 1521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Extract individual target operands from matched address AM. 1541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand void getAddressOperands(const SystemZAddressingMode &AM, EVT VT, 1558dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Base, SDValue &Disp) const; 1561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand void getAddressOperands(const SystemZAddressingMode &AM, EVT VT, 1578dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Base, SDValue &Disp, SDValue &Index) const; 1581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Try to match Addr as a FormBD address with displacement type DR. 1601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Return true on success, storing the base and displacement in 1611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Base and Disp respectively. 1621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool selectBDAddr(SystemZAddressingMode::DispRange DR, SDValue Addr, 1638dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Base, SDValue &Disp) const; 1641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16565ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford // Try to match Addr as a FormBDX address with displacement type DR. 16665ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford // Return true on success and if the result had no index. Store the 16765ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford // base and displacement in Base and Disp respectively. 16865ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford bool selectMVIAddr(SystemZAddressingMode::DispRange DR, SDValue Addr, 1698dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Base, SDValue &Disp) const; 17065ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford 1711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Try to match Addr as a FormBDX* address of form Form with 1721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // displacement type DR. Return true on success, storing the base, 1731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // displacement and index in Base, Disp and Index respectively. 1741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool selectBDXAddr(SystemZAddressingMode::AddrForm Form, 1751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode::DispRange DR, SDValue Addr, 1768dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Base, SDValue &Disp, SDValue &Index) const; 1771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // PC-relative address matching routines used by SystemZOperands.td. 1798dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool selectPCRelAddress(SDValue Addr, SDValue &Target) const { 1808dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford if (SystemZISD::isPCREL(Addr.getOpcode())) { 1811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Target = Addr.getOperand(0); 1821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 1831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 1851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // BD matching routines used by SystemZOperands.td. 1888dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool selectBDAddr12Only(SDValue Addr, SDValue &Base, SDValue &Disp) const { 1891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return selectBDAddr(SystemZAddressingMode::Disp12Only, Addr, Base, Disp); 1901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1918dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool selectBDAddr12Pair(SDValue Addr, SDValue &Base, SDValue &Disp) const { 1921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return selectBDAddr(SystemZAddressingMode::Disp12Pair, Addr, Base, Disp); 1931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1948dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool selectBDAddr20Only(SDValue Addr, SDValue &Base, SDValue &Disp) const { 1951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return selectBDAddr(SystemZAddressingMode::Disp20Only, Addr, Base, Disp); 1961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1978dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool selectBDAddr20Pair(SDValue Addr, SDValue &Base, SDValue &Disp) const { 1981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return selectBDAddr(SystemZAddressingMode::Disp20Pair, Addr, Base, Disp); 1991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 20165ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford // MVI matching routines used by SystemZOperands.td. 2028dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool selectMVIAddr12Pair(SDValue Addr, SDValue &Base, SDValue &Disp) const { 20365ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford return selectMVIAddr(SystemZAddressingMode::Disp12Pair, Addr, Base, Disp); 20465ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford } 2058dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool selectMVIAddr20Pair(SDValue Addr, SDValue &Base, SDValue &Disp) const { 20665ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford return selectMVIAddr(SystemZAddressingMode::Disp20Pair, Addr, Base, Disp); 20765ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford } 20865ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford 2091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // BDX matching routines used by SystemZOperands.td. 2101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool selectBDXAddr12Only(SDValue Addr, SDValue &Base, SDValue &Disp, 2118dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Index) const { 2121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return selectBDXAddr(SystemZAddressingMode::FormBDXNormal, 2131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode::Disp12Only, 2141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Addr, Base, Disp, Index); 2151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool selectBDXAddr12Pair(SDValue Addr, SDValue &Base, SDValue &Disp, 2178dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Index) const { 2181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return selectBDXAddr(SystemZAddressingMode::FormBDXNormal, 2191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode::Disp12Pair, 2201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Addr, Base, Disp, Index); 2211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool selectDynAlloc12Only(SDValue Addr, SDValue &Base, SDValue &Disp, 2238dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Index) const { 2241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return selectBDXAddr(SystemZAddressingMode::FormBDXDynAlloc, 2251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode::Disp12Only, 2261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Addr, Base, Disp, Index); 2271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool selectBDXAddr20Only(SDValue Addr, SDValue &Base, SDValue &Disp, 2298dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Index) const { 2301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return selectBDXAddr(SystemZAddressingMode::FormBDXNormal, 2311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode::Disp20Only, 2321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Addr, Base, Disp, Index); 2331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool selectBDXAddr20Only128(SDValue Addr, SDValue &Base, SDValue &Disp, 2358dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Index) const { 2361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return selectBDXAddr(SystemZAddressingMode::FormBDXNormal, 2371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode::Disp20Only128, 2381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Addr, Base, Disp, Index); 2391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool selectBDXAddr20Pair(SDValue Addr, SDValue &Base, SDValue &Disp, 2418dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Index) const { 2421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return selectBDXAddr(SystemZAddressingMode::FormBDXNormal, 2431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode::Disp20Pair, 2441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Addr, Base, Disp, Index); 2451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool selectLAAddr12Pair(SDValue Addr, SDValue &Base, SDValue &Disp, 2478dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Index) const { 2481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return selectBDXAddr(SystemZAddressingMode::FormBDXLA, 2491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode::Disp12Pair, 2501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Addr, Base, Disp, Index); 2511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool selectLAAddr20Pair(SDValue Addr, SDValue &Base, SDValue &Disp, 2538dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Index) const { 2541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return selectBDXAddr(SystemZAddressingMode::FormBDXLA, 2551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode::Disp20Pair, 2561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Addr, Base, Disp, Index); 2571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 259de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // Check whether (or Op (and X InsertMask)) is effectively an insertion 260de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // of X into bits InsertMask of some Y != Op. Return true if so and 261de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // set Op to that Y. 2628dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool detectOrAndInsertion(SDValue &Op, uint64_t InsertMask) const; 263de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford 264b3f912b510f8040690864126351b7021980558bbRichard Sandiford // Try to update RxSBG so that only the bits of RxSBG.Input in Mask are used. 265b3f912b510f8040690864126351b7021980558bbRichard Sandiford // Return true on success. 2668dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool refineRxSBGMask(RxSBGOperands &RxSBG, uint64_t Mask) const; 267b3f912b510f8040690864126351b7021980558bbRichard Sandiford 268efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford // Try to fold some of RxSBG.Input into other fields of RxSBG. 269efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford // Return true on success. 2708dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool expandRxSBG(RxSBGOperands &RxSBG) const; 271376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 272f985f01574956da0d42e33d440deb63bf153d354Richard Sandiford // Return an undefined value of type VT. 273f985f01574956da0d42e33d440deb63bf153d354Richard Sandiford SDValue getUNDEF(SDLoc DL, EVT VT) const; 274b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford 275b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford // Convert N to VT, if it isn't already. 2768dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue convertTo(SDLoc DL, EVT VT, SDValue N) const; 277b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford 278376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford // Try to implement AND or shift node N using RISBG with the zero flag set. 279376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford // Return the selected node on success, otherwise return null. 280376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford SDNode *tryRISBGZero(SDNode *N); 281b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford 28230a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford // Try to use RISBG or Opcode to implement OR or XOR node N. 28330a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford // Return the selected node on success, otherwise return null. 28430a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford SDNode *tryRxSBG(SDNode *N, unsigned Opcode); 285de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford 2861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If Op0 is null, then Node is a constant that can be loaded using: 2871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // 2881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // (Opcode UpperVal LowerVal) 2891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // 2901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If Op0 is nonnull, then Node can be implemented using: 2911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // 2921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // (Opcode (Opcode Op0 UpperVal) LowerVal) 2931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDNode *splitLargeImmediate(unsigned Opcode, SDNode *Node, SDValue Op0, 2941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t UpperVal, uint64_t LowerVal); 2951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2960548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // Return true if Load and Store are loads and stores of the same size 2970548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // and are guaranteed not to overlap. Such operations can be implemented 2980548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // using block (SS-format) instructions. 2990548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // 3000548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // Partial overlap would lead to incorrect code, since the block operations 3010548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // are logically bytewise, even though they have a fast path for the 3020548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // non-overlapping case. We also need to avoid full overlap (i.e. two 3030548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // addresses that might be equal at run time) because although that case 3040548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // would be handled correctly, it might be implemented by millicode. 3050548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford bool canUseBlockOperation(StoreSDNode *Store, LoadSDNode *Load) const; 3060548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford 30716277c4698f36a756c540fae326874774156aaedRichard Sandiford // N is a (store (load Y), X) pattern. Return true if it can use an MVC 30816277c4698f36a756c540fae326874774156aaedRichard Sandiford // from Y to X. 3092e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford bool storeLoadCanUseMVC(SDNode *N) const; 3102e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford 31116277c4698f36a756c540fae326874774156aaedRichard Sandiford // N is a (store (op (load A[0]), (load A[1])), X) pattern. Return true 31216277c4698f36a756c540fae326874774156aaedRichard Sandiford // if A[1 - I] == X and if N can use a block operation like NC from A[I] 31316277c4698f36a756c540fae326874774156aaedRichard Sandiford // to X. 31416277c4698f36a756c540fae326874774156aaedRichard Sandiford bool storeLoadCanUseBlockBinary(SDNode *N, unsigned I) const; 31516277c4698f36a756c540fae326874774156aaedRichard Sandiford 3161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandpublic: 3171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZDAGToDAGISel(SystemZTargetMachine &TM, CodeGenOpt::Level OptLevel) 3181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand : SelectionDAGISel(TM, OptLevel), 3191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Lowering(*TM.getTargetLowering()), 3201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Subtarget(*TM.getSubtargetImpl()) { } 3211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Override MachineFunctionPass. 32336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const char *getPassName() const override { 3241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return "SystemZ DAG->DAG Pattern Instruction Selection"; 3251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Override SelectionDAGISel. 32836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SDNode *Select(SDNode *Node) override; 32936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, 33036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::vector<SDValue> &OutOps) override; 3311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Include the pieces autogenerated from the target description. 3331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand #include "SystemZGenDAGISel.inc" 3341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand}; 3351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} // end anonymous namespace 3361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandFunctionPass *llvm::createSystemZISelDag(SystemZTargetMachine &TM, 3381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CodeGenOpt::Level OptLevel) { 3391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return new SystemZDAGToDAGISel(TM, OptLevel); 3401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Return true if Val should be selected as a displacement for an address 3431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// with range DR. Here we're interested in the range of both the instruction 3441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// described by DR and of any pairing instruction. 3451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic bool selectDisp(SystemZAddressingMode::DispRange DR, int64_t Val) { 3461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (DR) { 3471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZAddressingMode::Disp12Only: 3481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return isUInt<12>(Val); 3491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZAddressingMode::Disp12Pair: 3511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZAddressingMode::Disp20Only: 3521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZAddressingMode::Disp20Pair: 3531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return isInt<20>(Val); 3541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZAddressingMode::Disp20Only128: 3561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return isInt<20>(Val) && isInt<20>(Val + 8); 3571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Unhandled displacement range"); 3591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Change the base or index in AM to Value, where IsBase selects 3621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// between the base and index. 3631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic void changeComponent(SystemZAddressingMode &AM, bool IsBase, 3641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Value) { 3651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsBase) 3661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand AM.Base = Value; 3671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 3681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand AM.Index = Value; 3691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// The base or index of AM is equivalent to Value + ADJDYNALLOC, 3721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// where IsBase selects between the base and index. Try to fold the 3731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// ADJDYNALLOC into AM. 3741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic bool expandAdjDynAlloc(SystemZAddressingMode &AM, bool IsBase, 3751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Value) { 3761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (AM.isDynAlloc() && !AM.IncludesDynAlloc) { 3771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand changeComponent(AM, IsBase, Value); 3781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand AM.IncludesDynAlloc = true; 3791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 3801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 3821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// The base of AM is equivalent to Base + Index. Try to use Index as 3851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// the index register. 3861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic bool expandIndex(SystemZAddressingMode &AM, SDValue Base, 3871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Index) { 3881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (AM.hasIndexField() && !AM.Index.getNode()) { 3891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand AM.Base = Base; 3901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand AM.Index = Index; 3911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 3921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 3941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// The base or index of AM is equivalent to Op0 + Op1, where IsBase selects 3971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// between the base and index. Try to fold Op1 into AM's displacement. 3981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic bool expandDisp(SystemZAddressingMode &AM, bool IsBase, 3998dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue Op0, uint64_t Op1) { 4001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // First try adjusting the displacement. 4018dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford int64_t TestDisp = AM.Disp + Op1; 4021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (selectDisp(AM.DR, TestDisp)) { 4031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand changeComponent(AM, IsBase, Op0); 4041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand AM.Disp = TestDisp; 4051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 4061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 4071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We could consider forcing the displacement into a register and 4091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // using it as an index, but it would need to be carefully tuned. 4101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 4111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 4121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool SystemZDAGToDAGISel::expandAddress(SystemZAddressingMode &AM, 4148dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool IsBase) const { 4151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue N = IsBase ? AM.Base : AM.Index; 4161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Opcode = N.getOpcode(); 4171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Opcode == ISD::TRUNCATE) { 4181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand N = N.getOperand(0); 4191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = N.getOpcode(); 4201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 4211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Opcode == ISD::ADD || CurDAG->isBaseWithConstantOffset(N)) { 4221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Op0 = N.getOperand(0); 4231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Op1 = N.getOperand(1); 4241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Op0Code = Op0->getOpcode(); 4261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Op1Code = Op1->getOpcode(); 4271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Op0Code == SystemZISD::ADJDYNALLOC) 4291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return expandAdjDynAlloc(AM, IsBase, Op1); 4301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Op1Code == SystemZISD::ADJDYNALLOC) 4311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return expandAdjDynAlloc(AM, IsBase, Op0); 4321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Op0Code == ISD::Constant) 4348dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford return expandDisp(AM, IsBase, Op1, 4358dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford cast<ConstantSDNode>(Op0)->getSExtValue()); 4361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Op1Code == ISD::Constant) 4378dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford return expandDisp(AM, IsBase, Op0, 4388dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford cast<ConstantSDNode>(Op1)->getSExtValue()); 4391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsBase && expandIndex(AM, Op0, Op1)) 4411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 4421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 4438dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford if (Opcode == SystemZISD::PCREL_OFFSET) { 4448dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue Full = N.getOperand(0); 4458dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue Base = N.getOperand(1); 4468dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue Anchor = Base.getOperand(0); 4478dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford uint64_t Offset = (cast<GlobalAddressSDNode>(Full)->getOffset() - 4488dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford cast<GlobalAddressSDNode>(Anchor)->getOffset()); 4498dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford return expandDisp(AM, IsBase, Base, Offset); 4508dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford } 4511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 4521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 4531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Return true if an instruction with displacement range DR should be 4551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// used for displacement value Val. selectDisp(DR, Val) must already hold. 4561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic bool isValidDisp(SystemZAddressingMode::DispRange DR, int64_t Val) { 4571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(selectDisp(DR, Val) && "Invalid displacement"); 4581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (DR) { 4591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZAddressingMode::Disp12Only: 4601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZAddressingMode::Disp20Only: 4611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZAddressingMode::Disp20Only128: 4621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 4631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZAddressingMode::Disp12Pair: 4651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Use the other instruction if the displacement is too large. 4661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return isUInt<12>(Val); 4671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZAddressingMode::Disp20Pair: 4691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Use the other instruction if the displacement is small enough. 4701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return !isUInt<12>(Val); 4711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 4721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Unhandled displacement range"); 4731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 4741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Return true if Base + Disp + Index should be performed by LA(Y). 4761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic bool shouldUseLA(SDNode *Base, int64_t Disp, SDNode *Index) { 4771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Don't use LA(Y) for constants. 4781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!Base) 4791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 4801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Always use LA(Y) for frame addresses, since we know that the destination 4821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // register is almost always (perhaps always) going to be different from 4831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // the frame register. 4841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Base->getOpcode() == ISD::FrameIndex) 4851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 4861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Disp) { 4881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Always use LA(Y) if there is a base, displacement and index. 4891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Index) 4901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 4911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Always use LA if the displacement is small enough. It should always 4931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // be no worse than AGHI (and better if it avoids a move). 4941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isUInt<12>(Disp)) 4951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 4961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // For similar reasons, always use LAY if the constant is too big for AGHI. 4981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // LAY should be no worse than AGFI. 4991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!isInt<16>(Disp)) 5001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 5011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else { 5021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Don't use LA for plain registers. 5031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!Index) 5041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 5051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Don't use LA for plain addition if the index operand is only used 5071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // once. It should be a natural two-operand addition in that case. 5081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Index->hasOneUse()) 5091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 5101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Prefer addition if the second operation is sign-extended, in the 5121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // hope of using AGF. 5131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned IndexOpcode = Index->getOpcode(); 5141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IndexOpcode == ISD::SIGN_EXTEND || 5151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand IndexOpcode == ISD::SIGN_EXTEND_INREG) 5161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 5171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 5181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Don't use LA for two-operand addition if either operand is only 5201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // used once. The addition instructions are better in that case. 5211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Base->hasOneUse()) 5221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 5231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 5251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 5261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Return true if Addr is suitable for AM, updating AM if so. 5281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool SystemZDAGToDAGISel::selectAddress(SDValue Addr, 5298dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SystemZAddressingMode &AM) const { 5301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Start out assuming that the address will need to be loaded separately, 5311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // then try to extend it as much as we can. 5321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand AM.Base = Addr; 5331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // First try treating the address as a constant. 5351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Addr.getOpcode() == ISD::Constant && 5368dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford expandDisp(AM, true, SDValue(), 5378dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford cast<ConstantSDNode>(Addr)->getSExtValue())) 5381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ; 5391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 5401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Otherwise try expanding each component. 5411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand while (expandAddress(AM, true) || 5421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand (AM.Index.getNode() && expandAddress(AM, false))) 5431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 5441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Reject cases where it isn't profitable to use LA(Y). 5461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (AM.Form == SystemZAddressingMode::FormBDXLA && 5471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand !shouldUseLA(AM.Base.getNode(), AM.Disp, AM.Index.getNode())) 5481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 5491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Reject cases where the other instruction in a pair should be used. 5511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!isValidDisp(AM.DR, AM.Disp)) 5521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 5531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Make sure that ADJDYNALLOC is included where necessary. 5551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (AM.isDynAlloc() && !AM.IncludesDynAlloc) 5561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 5571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DEBUG(AM.dump()); 5591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 5601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 5611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Insert a node into the DAG at least before Pos. This will reposition 5631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// the node as needed, and will assign it a node ID that is <= Pos's ID. 5641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Note that this does *not* preserve the uniqueness of node IDs! 5651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// The selection DAG must no longer depend on their uniqueness when this 5661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// function is used. 5671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic void insertDAGNode(SelectionDAG *DAG, SDNode *Pos, SDValue N) { 5681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (N.getNode()->getNodeId() == -1 || 5691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand N.getNode()->getNodeId() > Pos->getNodeId()) { 5701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG->RepositionNode(Pos, N.getNode()); 5711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand N.getNode()->setNodeId(Pos->getNodeId()); 5721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 5731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 5741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZDAGToDAGISel::getAddressOperands(const SystemZAddressingMode &AM, 5761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT VT, SDValue &Base, 5778dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Disp) const { 5781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Base = AM.Base; 5791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!Base.getNode()) 5801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Register 0 means "no base". This is mostly useful for shifts. 5811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Base = CurDAG->getRegister(0, VT); 5821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (Base.getOpcode() == ISD::FrameIndex) { 5831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Lower a FrameIndex to a TargetFrameIndex. 5841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t FrameIndex = cast<FrameIndexSDNode>(Base)->getIndex(); 5851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Base = CurDAG->getTargetFrameIndex(FrameIndex, VT); 5861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (Base.getValueType() != VT) { 5871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Truncate values from i64 to i32, for shifts. 5881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(VT == MVT::i32 && Base.getValueType() == MVT::i64 && 5891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand "Unexpected truncation"); 590ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Base); 5911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Trunc = CurDAG->getNode(ISD::TRUNCATE, DL, VT, Base); 5921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand insertDAGNode(CurDAG, Base.getNode(), Trunc); 5931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Base = Trunc; 5941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 5951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Lower the displacement to a TargetConstant. 5971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Disp = CurDAG->getTargetConstant(AM.Disp, VT); 5981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 5991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZDAGToDAGISel::getAddressOperands(const SystemZAddressingMode &AM, 6011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT VT, SDValue &Base, 6028dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Disp, 6038dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Index) const { 6041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand getAddressOperands(AM, VT, Base, Disp); 6051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Index = AM.Index; 6071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!Index.getNode()) 6081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Register 0 means "no index". 6091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Index = CurDAG->getRegister(0, VT); 6101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 6111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool SystemZDAGToDAGISel::selectBDAddr(SystemZAddressingMode::DispRange DR, 6131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Addr, SDValue &Base, 6148dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Disp) const { 6151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode AM(SystemZAddressingMode::FormBD, DR); 6161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!selectAddress(Addr, AM)) 6171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 6181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand getAddressOperands(AM, Addr.getValueType(), Base, Disp); 6201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 6211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 6221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 62365ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandifordbool SystemZDAGToDAGISel::selectMVIAddr(SystemZAddressingMode::DispRange DR, 62465ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford SDValue Addr, SDValue &Base, 6258dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Disp) const { 62665ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford SystemZAddressingMode AM(SystemZAddressingMode::FormBDXNormal, DR); 62765ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford if (!selectAddress(Addr, AM) || AM.Index.getNode()) 62865ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford return false; 62965ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford 63065ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford getAddressOperands(AM, Addr.getValueType(), Base, Disp); 63165ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford return true; 63265ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford} 63365ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford 6341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool SystemZDAGToDAGISel::selectBDXAddr(SystemZAddressingMode::AddrForm Form, 6351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode::DispRange DR, 6361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Addr, SDValue &Base, 6378dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Disp, SDValue &Index) const { 6381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode AM(Form, DR); 6391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!selectAddress(Addr, AM)) 6401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 6411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand getAddressOperands(AM, Addr.getValueType(), Base, Disp, Index); 6431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 6441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 6451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 646de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandifordbool SystemZDAGToDAGISel::detectOrAndInsertion(SDValue &Op, 6478dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford uint64_t InsertMask) const { 648de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // We're only interested in cases where the insertion is into some operand 649de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // of Op, rather than into Op itself. The only useful case is an AND. 650de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford if (Op.getOpcode() != ISD::AND) 651de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford return false; 652de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford 653de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // We need a constant mask. 65436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto *MaskNode = dyn_cast<ConstantSDNode>(Op.getOperand(1).getNode()); 655de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford if (!MaskNode) 656de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford return false; 657de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford 658de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // It's not an insertion of Op.getOperand(0) if the two masks overlap. 659de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford uint64_t AndMask = MaskNode->getZExtValue(); 660de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford if (InsertMask & AndMask) 661de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford return false; 662de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford 663de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // It's only an insertion if all bits are covered or are known to be zero. 664de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // The inner check covers all cases but is more expensive. 665de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford uint64_t Used = allOnes(Op.getValueType().getSizeInBits()); 666de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford if (Used != (AndMask | InsertMask)) { 667de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford APInt KnownZero, KnownOne; 668dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CurDAG->computeKnownBits(Op.getOperand(0), KnownZero, KnownOne); 669de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford if (Used != (AndMask | InsertMask | KnownZero.getZExtValue())) 670de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford return false; 671de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford } 672de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford 673de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford Op = Op.getOperand(0); 674de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford return true; 675de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford} 676de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford 6778dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandifordbool SystemZDAGToDAGISel::refineRxSBGMask(RxSBGOperands &RxSBG, 6788dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford uint64_t Mask) const { 679b3f912b510f8040690864126351b7021980558bbRichard Sandiford const SystemZInstrInfo *TII = getInstrInfo(); 680efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford if (RxSBG.Rotate != 0) 681efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford Mask = (Mask << RxSBG.Rotate) | (Mask >> (64 - RxSBG.Rotate)); 682efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford Mask &= RxSBG.Mask; 683b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (TII->isRxSBGMask(Mask, RxSBG.BitSize, RxSBG.Start, RxSBG.End)) { 684efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford RxSBG.Mask = Mask; 685efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford return true; 686efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford } 687b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford return false; 688b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford} 689b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford 69086a735396ab4804a06e76d1b4ce49dbd44c35827Richard Sandiford// Return true if any bits of (RxSBG.Input & Mask) are significant. 69186a735396ab4804a06e76d1b4ce49dbd44c35827Richard Sandifordstatic bool maskMatters(RxSBGOperands &RxSBG, uint64_t Mask) { 69286a735396ab4804a06e76d1b4ce49dbd44c35827Richard Sandiford // Rotate the mask in the same way as RxSBG.Input is rotated. 6939dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford if (RxSBG.Rotate != 0) 69486a735396ab4804a06e76d1b4ce49dbd44c35827Richard Sandiford Mask = ((Mask << RxSBG.Rotate) | (Mask >> (64 - RxSBG.Rotate))); 69586a735396ab4804a06e76d1b4ce49dbd44c35827Richard Sandiford return (Mask & RxSBG.Mask) != 0; 6969dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford} 6979dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford 6988dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandifordbool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG) const { 699efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford SDValue N = RxSBG.Input; 7009dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford unsigned Opcode = N.getOpcode(); 7019dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford switch (Opcode) { 702376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford case ISD::AND: { 703722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford if (RxSBG.Opcode == SystemZ::RNSBG) 704722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford return false; 705722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford 70636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto *MaskNode = dyn_cast<ConstantSDNode>(N.getOperand(1).getNode()); 707376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford if (!MaskNode) 708376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return false; 709376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 710376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford SDValue Input = N.getOperand(0); 711376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford uint64_t Mask = MaskNode->getZExtValue(); 712efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford if (!refineRxSBGMask(RxSBG, Mask)) { 713376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford // If some bits of Input are already known zeros, those bits will have 714376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford // been removed from the mask. See if adding them back in makes the 715376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford // mask suitable. 716376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford APInt KnownZero, KnownOne; 717dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CurDAG->computeKnownBits(Input, KnownZero, KnownOne); 718376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford Mask |= KnownZero.getZExtValue(); 719efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford if (!refineRxSBGMask(RxSBG, Mask)) 720376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return false; 721376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford } 722efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford RxSBG.Input = Input; 723376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return true; 724376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford } 725376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 726722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford case ISD::OR: { 727722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford if (RxSBG.Opcode != SystemZ::RNSBG) 728722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford return false; 729722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford 73036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto *MaskNode = dyn_cast<ConstantSDNode>(N.getOperand(1).getNode()); 731722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford if (!MaskNode) 732722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford return false; 733722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford 734722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford SDValue Input = N.getOperand(0); 735722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford uint64_t Mask = ~MaskNode->getZExtValue(); 736722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford if (!refineRxSBGMask(RxSBG, Mask)) { 737722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford // If some bits of Input are already known ones, those bits will have 738722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford // been removed from the mask. See if adding them back in makes the 739722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford // mask suitable. 740722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford APInt KnownZero, KnownOne; 741dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CurDAG->computeKnownBits(Input, KnownZero, KnownOne); 742722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford Mask &= ~KnownOne.getZExtValue(); 743722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford if (!refineRxSBGMask(RxSBG, Mask)) 744722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford return false; 745722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford } 746722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford RxSBG.Input = Input; 747722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford return true; 748722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford } 749722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford 750376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford case ISD::ROTL: { 751efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford // Any 64-bit rotate left can be merged into the RxSBG. 752d77a7669ec1a6bba7e45791b1aa1e65a603dda92Richard Sandiford if (RxSBG.BitSize != 64 || N.getValueType() != MVT::i64) 753376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return false; 75436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto *CountNode = dyn_cast<ConstantSDNode>(N.getOperand(1).getNode()); 755376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford if (!CountNode) 756376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return false; 757376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 758efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford RxSBG.Rotate = (RxSBG.Rotate + CountNode->getZExtValue()) & 63; 759efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford RxSBG.Input = N.getOperand(0); 760376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return true; 761376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford } 762376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 76336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ISD::ANY_EXTEND: 76436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Bits above the extended operand are don't-care. 76536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RxSBG.Input = N.getOperand(0); 76636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 76736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 768d77a7669ec1a6bba7e45791b1aa1e65a603dda92Richard Sandiford case ISD::ZERO_EXTEND: 76936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (RxSBG.Opcode != SystemZ::RNSBG) { 77036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Restrict the mask to the extended operand. 77136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned InnerBitSize = N.getOperand(0).getValueType().getSizeInBits(); 77236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!refineRxSBGMask(RxSBG, allOnes(InnerBitSize))) 77336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 77436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 77536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RxSBG.Input = N.getOperand(0); 77636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 77736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 77836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Fall through. 77936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 78036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ISD::SIGN_EXTEND: { 781d77a7669ec1a6bba7e45791b1aa1e65a603dda92Richard Sandiford // Check that the extension bits are don't-care (i.e. are masked out 782d77a7669ec1a6bba7e45791b1aa1e65a603dda92Richard Sandiford // by the final mask). 783d77a7669ec1a6bba7e45791b1aa1e65a603dda92Richard Sandiford unsigned InnerBitSize = N.getOperand(0).getValueType().getSizeInBits(); 78486a735396ab4804a06e76d1b4ce49dbd44c35827Richard Sandiford if (maskMatters(RxSBG, allOnes(RxSBG.BitSize) - allOnes(InnerBitSize))) 785d77a7669ec1a6bba7e45791b1aa1e65a603dda92Richard Sandiford return false; 786d77a7669ec1a6bba7e45791b1aa1e65a603dda92Richard Sandiford 787d77a7669ec1a6bba7e45791b1aa1e65a603dda92Richard Sandiford RxSBG.Input = N.getOperand(0); 788d77a7669ec1a6bba7e45791b1aa1e65a603dda92Richard Sandiford return true; 789d77a7669ec1a6bba7e45791b1aa1e65a603dda92Richard Sandiford } 790d77a7669ec1a6bba7e45791b1aa1e65a603dda92Richard Sandiford 791376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford case ISD::SHL: { 79236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto *CountNode = dyn_cast<ConstantSDNode>(N.getOperand(1).getNode()); 793376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford if (!CountNode) 794376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return false; 795376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 796376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford uint64_t Count = CountNode->getZExtValue(); 797d77a7669ec1a6bba7e45791b1aa1e65a603dda92Richard Sandiford unsigned BitSize = N.getValueType().getSizeInBits(); 798d77a7669ec1a6bba7e45791b1aa1e65a603dda92Richard Sandiford if (Count < 1 || Count >= BitSize) 799376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return false; 800376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 801722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford if (RxSBG.Opcode == SystemZ::RNSBG) { 802722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford // Treat (shl X, count) as (rotl X, size-count) as long as the bottom 803722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford // count bits from RxSBG.Input are ignored. 80486a735396ab4804a06e76d1b4ce49dbd44c35827Richard Sandiford if (maskMatters(RxSBG, allOnes(Count))) 805722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford return false; 806722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford } else { 807722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford // Treat (shl X, count) as (and (rotl X, count), ~0<<count). 808d77a7669ec1a6bba7e45791b1aa1e65a603dda92Richard Sandiford if (!refineRxSBGMask(RxSBG, allOnes(BitSize - Count) << Count)) 809722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford return false; 810722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford } 811722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford 812efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford RxSBG.Rotate = (RxSBG.Rotate + Count) & 63; 813efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford RxSBG.Input = N.getOperand(0); 814376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return true; 815376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford } 816376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 8179dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford case ISD::SRL: 818376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford case ISD::SRA: { 81936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto *CountNode = dyn_cast<ConstantSDNode>(N.getOperand(1).getNode()); 820376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford if (!CountNode) 821376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return false; 822376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 823376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford uint64_t Count = CountNode->getZExtValue(); 824d77a7669ec1a6bba7e45791b1aa1e65a603dda92Richard Sandiford unsigned BitSize = N.getValueType().getSizeInBits(); 825d77a7669ec1a6bba7e45791b1aa1e65a603dda92Richard Sandiford if (Count < 1 || Count >= BitSize) 826376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return false; 827376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 828722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford if (RxSBG.Opcode == SystemZ::RNSBG || Opcode == ISD::SRA) { 829722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford // Treat (srl|sra X, count) as (rotl X, size-count) as long as the top 830722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford // count bits from RxSBG.Input are ignored. 83186a735396ab4804a06e76d1b4ce49dbd44c35827Richard Sandiford if (maskMatters(RxSBG, allOnes(Count) << (BitSize - Count))) 8329dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford return false; 8339dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford } else { 8349dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford // Treat (srl X, count), mask) as (and (rotl X, size-count), ~0>>count), 8359dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford // which is similar to SLL above. 836d77a7669ec1a6bba7e45791b1aa1e65a603dda92Richard Sandiford if (!refineRxSBGMask(RxSBG, allOnes(BitSize - Count))) 8379dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford return false; 8389dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford } 8399dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford 8409dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford RxSBG.Rotate = (RxSBG.Rotate - Count) & 63; 841efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford RxSBG.Input = N.getOperand(0); 842376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return true; 843376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford } 844376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford default: 845376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return false; 846376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford } 847376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford} 848376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 849f985f01574956da0d42e33d440deb63bf153d354Richard SandifordSDValue SystemZDAGToDAGISel::getUNDEF(SDLoc DL, EVT VT) const { 850f985f01574956da0d42e33d440deb63bf153d354Richard Sandiford SDNode *N = CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, VT); 851b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford return SDValue(N, 0); 852b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford} 853b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford 8548dac19c0708c9bd0da0b832014918e00ded44d86Richard SandifordSDValue SystemZDAGToDAGISel::convertTo(SDLoc DL, EVT VT, SDValue N) const { 8557c7b431d2fa3ead0a2a24c4dd81fc92f293203ddRichard Sandiford if (N.getValueType() == MVT::i32 && VT == MVT::i64) 856745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford return CurDAG->getTargetInsertSubreg(SystemZ::subreg_l32, 857f985f01574956da0d42e33d440deb63bf153d354Richard Sandiford DL, VT, getUNDEF(DL, MVT::i64), N); 8587c7b431d2fa3ead0a2a24c4dd81fc92f293203ddRichard Sandiford if (N.getValueType() == MVT::i64 && VT == MVT::i32) 859745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford return CurDAG->getTargetExtractSubreg(SystemZ::subreg_l32, DL, VT, N); 860b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford assert(N.getValueType() == VT && "Unexpected value types"); 861b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford return N; 862b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford} 863b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford 864376452165863fad987c890d9773e6eb87742a3e1Richard SandifordSDNode *SystemZDAGToDAGISel::tryRISBGZero(SDNode *N) { 865b3f912b510f8040690864126351b7021980558bbRichard Sandiford EVT VT = N->getValueType(0); 866722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford RxSBGOperands RISBG(SystemZ::RISBG, SDValue(N, 0)); 867376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford unsigned Count = 0; 868efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford while (expandRxSBG(RISBG)) 869d77a7669ec1a6bba7e45791b1aa1e65a603dda92Richard Sandiford if (RISBG.Input.getOpcode() != ISD::ANY_EXTEND) 870d77a7669ec1a6bba7e45791b1aa1e65a603dda92Richard Sandiford Count += 1; 871b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (Count == 0) 872dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 873b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (Count == 1) { 874b3f912b510f8040690864126351b7021980558bbRichard Sandiford // Prefer to use normal shift instructions over RISBG, since they can handle 875b3f912b510f8040690864126351b7021980558bbRichard Sandiford // all cases and are sometimes shorter. 876b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (N->getOpcode() != ISD::AND) 877dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 878b3f912b510f8040690864126351b7021980558bbRichard Sandiford 879b3f912b510f8040690864126351b7021980558bbRichard Sandiford // Prefer register extensions like LLC over RISBG. Also prefer to start 880b3f912b510f8040690864126351b7021980558bbRichard Sandiford // out with normal ANDs if one instruction would be enough. We can convert 881b3f912b510f8040690864126351b7021980558bbRichard Sandiford // these ANDs into an RISBG later if a three-address instruction is useful. 882b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (VT == MVT::i32 || 883b3f912b510f8040690864126351b7021980558bbRichard Sandiford RISBG.Mask == 0xff || 884b3f912b510f8040690864126351b7021980558bbRichard Sandiford RISBG.Mask == 0xffff || 885b3f912b510f8040690864126351b7021980558bbRichard Sandiford SystemZ::isImmLF(~RISBG.Mask) || 886b3f912b510f8040690864126351b7021980558bbRichard Sandiford SystemZ::isImmHF(~RISBG.Mask)) { 887b3f912b510f8040690864126351b7021980558bbRichard Sandiford // Force the new mask into the DAG, since it may include known-one bits. 88836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto *MaskN = cast<ConstantSDNode>(N->getOperand(1).getNode()); 889b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (MaskN->getZExtValue() != RISBG.Mask) { 890b3f912b510f8040690864126351b7021980558bbRichard Sandiford SDValue NewMask = CurDAG->getConstant(RISBG.Mask, VT); 891b3f912b510f8040690864126351b7021980558bbRichard Sandiford N = CurDAG->UpdateNodeOperands(N, N->getOperand(0), NewMask); 892b3f912b510f8040690864126351b7021980558bbRichard Sandiford return SelectCode(N); 893b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 894dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 895b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 896b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 897b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford 898f985f01574956da0d42e33d440deb63bf153d354Richard Sandiford unsigned Opcode = SystemZ::RISBG; 899f985f01574956da0d42e33d440deb63bf153d354Richard Sandiford EVT OpcodeVT = MVT::i64; 900f985f01574956da0d42e33d440deb63bf153d354Richard Sandiford if (VT == MVT::i32 && Subtarget.hasHighWord()) { 901f985f01574956da0d42e33d440deb63bf153d354Richard Sandiford Opcode = SystemZ::RISBMux; 902f985f01574956da0d42e33d440deb63bf153d354Richard Sandiford OpcodeVT = MVT::i32; 903f985f01574956da0d42e33d440deb63bf153d354Richard Sandiford RISBG.Start &= 31; 904f985f01574956da0d42e33d440deb63bf153d354Richard Sandiford RISBG.End &= 31; 905f985f01574956da0d42e33d440deb63bf153d354Richard Sandiford } 906b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford SDValue Ops[5] = { 907f985f01574956da0d42e33d440deb63bf153d354Richard Sandiford getUNDEF(SDLoc(N), OpcodeVT), 908f985f01574956da0d42e33d440deb63bf153d354Richard Sandiford convertTo(SDLoc(N), OpcodeVT, RISBG.Input), 909376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford CurDAG->getTargetConstant(RISBG.Start, MVT::i32), 910376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford CurDAG->getTargetConstant(RISBG.End | 128, MVT::i32), 911376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford CurDAG->getTargetConstant(RISBG.Rotate, MVT::i32) 912b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford }; 913f985f01574956da0d42e33d440deb63bf153d354Richard Sandiford N = CurDAG->getMachineNode(Opcode, SDLoc(N), OpcodeVT, Ops); 914b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford return convertTo(SDLoc(N), VT, SDValue(N, 0)).getNode(); 915b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford} 916b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford 91730a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard SandifordSDNode *SystemZDAGToDAGISel::tryRxSBG(SDNode *N, unsigned Opcode) { 91830a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford // Try treating each operand of N as the second operand of the RxSBG 919de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // and see which goes deepest. 920722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford RxSBGOperands RxSBG[] = { 921722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford RxSBGOperands(Opcode, N->getOperand(0)), 922722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford RxSBGOperands(Opcode, N->getOperand(1)) 923722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford }; 924de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford unsigned Count[] = { 0, 0 }; 925de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford for (unsigned I = 0; I < 2; ++I) 926efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford while (expandRxSBG(RxSBG[I])) 927d77a7669ec1a6bba7e45791b1aa1e65a603dda92Richard Sandiford if (RxSBG[I].Input.getOpcode() != ISD::ANY_EXTEND) 928d77a7669ec1a6bba7e45791b1aa1e65a603dda92Richard Sandiford Count[I] += 1; 929de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford 930de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // Do nothing if neither operand is suitable. 931de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford if (Count[0] == 0 && Count[1] == 0) 932dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 933de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford 934de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // Pick the deepest second operand. 935de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford unsigned I = Count[0] > Count[1] ? 0 : 1; 936de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford SDValue Op0 = N->getOperand(I ^ 1); 937de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford 938de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // Prefer IC for character insertions from memory. 93930a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford if (Opcode == SystemZ::ROSBG && (RxSBG[I].Mask & 0xff) == 0) 94036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (auto *Load = dyn_cast<LoadSDNode>(Op0.getNode())) 941de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford if (Load->getMemoryVT() == MVT::i8) 942dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 943de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford 944de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // See whether we can avoid an AND in the first operand by converting 945de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // ROSBG to RISBG. 94630a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford if (Opcode == SystemZ::ROSBG && detectOrAndInsertion(Op0, RxSBG[I].Mask)) 947de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford Opcode = SystemZ::RISBG; 948de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford 949de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford EVT VT = N->getValueType(0); 950de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford SDValue Ops[5] = { 951de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford convertTo(SDLoc(N), MVT::i64, Op0), 952efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford convertTo(SDLoc(N), MVT::i64, RxSBG[I].Input), 953efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford CurDAG->getTargetConstant(RxSBG[I].Start, MVT::i32), 954efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford CurDAG->getTargetConstant(RxSBG[I].End, MVT::i32), 955efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford CurDAG->getTargetConstant(RxSBG[I].Rotate, MVT::i32) 956de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford }; 957de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford N = CurDAG->getMachineNode(Opcode, SDLoc(N), MVT::i64, Ops); 958de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford return convertTo(SDLoc(N), VT, SDValue(N, 0)).getNode(); 959de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford} 960de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford 9611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDNode *SystemZDAGToDAGISel::splitLargeImmediate(unsigned Opcode, SDNode *Node, 9621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Op0, uint64_t UpperVal, 9631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t LowerVal) { 9641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT VT = Node->getValueType(0); 965ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Node); 9661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Upper = CurDAG->getConstant(UpperVal, VT); 9671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Op0.getNode()) 9681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Upper = CurDAG->getNode(Opcode, DL, VT, Op0, Upper); 9691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Upper = SDValue(Select(Upper.getNode()), 0); 9701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Lower = CurDAG->getConstant(LowerVal, VT); 9721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Or = CurDAG->getNode(Opcode, DL, VT, Upper, Lower); 9731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Or.getNode(); 9741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 9751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9760548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandifordbool SystemZDAGToDAGISel::canUseBlockOperation(StoreSDNode *Store, 9770548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford LoadSDNode *Load) const { 97816277c4698f36a756c540fae326874774156aaedRichard Sandiford // Check that the two memory operands have the same size. 97916277c4698f36a756c540fae326874774156aaedRichard Sandiford if (Load->getMemoryVT() != Store->getMemoryVT()) 98016277c4698f36a756c540fae326874774156aaedRichard Sandiford return false; 9812e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford 98216277c4698f36a756c540fae326874774156aaedRichard Sandiford // Volatility stops an access from being decomposed. 9832e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford if (Load->isVolatile() || Store->isVolatile()) 9842e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford return false; 9852e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford 9862e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford // There's no chance of overlap if the load is invariant. 9872e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford if (Load->isInvariant()) 9882e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford return true; 9892e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford 9902e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford // Otherwise we need to check whether there's an alias. 991dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const Value *V1 = Load->getMemOperand()->getValue(); 992dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const Value *V2 = Store->getMemOperand()->getValue(); 9932e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford if (!V1 || !V2) 9942e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford return false; 9952e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford 9960548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // Reject equality. 9970548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford uint64_t Size = Load->getMemoryVT().getStoreSize(); 9982e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford int64_t End1 = Load->getSrcValueOffset() + Size; 9992e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford int64_t End2 = Store->getSrcValueOffset() + Size; 10000548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford if (V1 == V2 && End1 == End2) 10010548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford return false; 10020548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford 10032e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford return !AA->alias(AliasAnalysis::Location(V1, End1, Load->getTBAAInfo()), 10042e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford AliasAnalysis::Location(V2, End2, Store->getTBAAInfo())); 10052e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford} 10062e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford 100716277c4698f36a756c540fae326874774156aaedRichard Sandifordbool SystemZDAGToDAGISel::storeLoadCanUseMVC(SDNode *N) const { 100836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto *Store = cast<StoreSDNode>(N); 100936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto *Load = cast<LoadSDNode>(Store->getValue()); 101016277c4698f36a756c540fae326874774156aaedRichard Sandiford 101116277c4698f36a756c540fae326874774156aaedRichard Sandiford // Prefer not to use MVC if either address can use ... RELATIVE LONG 101216277c4698f36a756c540fae326874774156aaedRichard Sandiford // instructions. 101316277c4698f36a756c540fae326874774156aaedRichard Sandiford uint64_t Size = Load->getMemoryVT().getStoreSize(); 101416277c4698f36a756c540fae326874774156aaedRichard Sandiford if (Size > 1 && Size <= 8) { 101516277c4698f36a756c540fae326874774156aaedRichard Sandiford // Prefer LHRL, LRL and LGRL. 10168dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford if (SystemZISD::isPCREL(Load->getBasePtr().getOpcode())) 101716277c4698f36a756c540fae326874774156aaedRichard Sandiford return false; 101816277c4698f36a756c540fae326874774156aaedRichard Sandiford // Prefer STHRL, STRL and STGRL. 10198dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford if (SystemZISD::isPCREL(Store->getBasePtr().getOpcode())) 102016277c4698f36a756c540fae326874774156aaedRichard Sandiford return false; 102116277c4698f36a756c540fae326874774156aaedRichard Sandiford } 102216277c4698f36a756c540fae326874774156aaedRichard Sandiford 10230548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford return canUseBlockOperation(Store, Load); 102416277c4698f36a756c540fae326874774156aaedRichard Sandiford} 102516277c4698f36a756c540fae326874774156aaedRichard Sandiford 102616277c4698f36a756c540fae326874774156aaedRichard Sandifordbool SystemZDAGToDAGISel::storeLoadCanUseBlockBinary(SDNode *N, 102716277c4698f36a756c540fae326874774156aaedRichard Sandiford unsigned I) const { 102836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto *StoreA = cast<StoreSDNode>(N); 102936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto *LoadA = cast<LoadSDNode>(StoreA->getValue().getOperand(1 - I)); 103036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto *LoadB = cast<LoadSDNode>(StoreA->getValue().getOperand(I)); 10310548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford return !LoadA->isVolatile() && canUseBlockOperation(StoreA, LoadB); 103216277c4698f36a756c540fae326874774156aaedRichard Sandiford} 103316277c4698f36a756c540fae326874774156aaedRichard Sandiford 10341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDNode *SystemZDAGToDAGISel::Select(SDNode *Node) { 10351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Dump information about the Node being selected 10361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DEBUG(errs() << "Selecting: "; Node->dump(CurDAG); errs() << "\n"); 10371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 10381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If we have a custom node, we already have selected! 10391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Node->isMachineOpcode()) { 10401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n"); 10413e84ad28d4d3ceee25771b1e30315c20b7608c39Tim Northover Node->setNodeId(-1); 1042dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 10431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 10441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 10451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Opcode = Node->getOpcode(); 1046dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SDNode *ResNode = nullptr; 10471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (Opcode) { 10481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::OR: 1049de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford if (Node->getOperand(1).getOpcode() != ISD::Constant) 105030a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford ResNode = tryRxSBG(Node, SystemZ::ROSBG); 105130a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford goto or_xor; 105230a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford 10531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::XOR: 105430a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford if (Node->getOperand(1).getOpcode() != ISD::Constant) 105530a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford ResNode = tryRxSBG(Node, SystemZ::RXSBG); 105630a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford // Fall through. 105730a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford or_xor: 10581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If this is a 64-bit operation in which both 32-bit halves are nonzero, 10591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // split the operation into two. 1060de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford if (!ResNode && Node->getValueType(0) == MVT::i64) 106136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (auto *Op1 = dyn_cast<ConstantSDNode>(Node->getOperand(1))) { 10621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t Val = Op1->getZExtValue(); 10631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!SystemZ::isImmLF(Val) && !SystemZ::isImmHF(Val)) 10641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Node = splitLargeImmediate(Opcode, Node, Node->getOperand(0), 10651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Val - uint32_t(Val), uint32_t(Val)); 10661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 10671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 10681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1069b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford case ISD::AND: 1070722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford if (Node->getOperand(1).getOpcode() != ISD::Constant) 1071722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford ResNode = tryRxSBG(Node, SystemZ::RNSBG); 1072722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford // Fall through. 1073376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford case ISD::ROTL: 1074376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford case ISD::SHL: 1075376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford case ISD::SRL: 107636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ISD::ZERO_EXTEND: 107730a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford if (!ResNode) 107830a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford ResNode = tryRISBGZero(Node); 1079b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford break; 1080b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford 10811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::Constant: 10821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If this is a 64-bit constant that is out of the range of LLILF, 10831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // LLIHF and LGFI, split it into two 32-bit pieces. 10841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Node->getValueType(0) == MVT::i64) { 10851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t Val = cast<ConstantSDNode>(Node)->getZExtValue(); 10861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!SystemZ::isImmLF(Val) && !SystemZ::isImmHF(Val) && !isInt<32>(Val)) 10871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Node = splitLargeImmediate(ISD::OR, Node, SDValue(), 10881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Val - uint32_t(Val), uint32_t(Val)); 10891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 10901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 10911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 109215715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford case SystemZISD::SELECT_CCMASK: { 109315715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford SDValue Op0 = Node->getOperand(0); 109415715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford SDValue Op1 = Node->getOperand(1); 109515715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford // Prefer to put any load first, so that it can be matched as a 109615715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford // conditional load. 109715715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford if (Op1.getOpcode() == ISD::LOAD && Op0.getOpcode() != ISD::LOAD) { 109815715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford SDValue CCValid = Node->getOperand(2); 109915715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford SDValue CCMask = Node->getOperand(3); 110015715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford uint64_t ConstCCValid = 110115715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford cast<ConstantSDNode>(CCValid.getNode())->getZExtValue(); 110215715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford uint64_t ConstCCMask = 110315715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford cast<ConstantSDNode>(CCMask.getNode())->getZExtValue(); 110415715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford // Invert the condition. 110515715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford CCMask = CurDAG->getConstant(ConstCCValid ^ ConstCCMask, 110615715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford CCMask.getValueType()); 110715715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford SDValue Op4 = Node->getOperand(4); 110815715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford Node = CurDAG->UpdateNodeOperands(Node, Op1, Op0, CCValid, CCMask, Op4); 110915715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford } 111015715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford break; 111115715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford } 11121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 11131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 11141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Select the default instruction 1115b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford if (!ResNode) 1116b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford ResNode = SelectCode(Node); 11171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 11181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DEBUG(errs() << "=> "; 1119dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (ResNode == nullptr || ResNode == Node) 11201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Node->dump(CurDAG); 11211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 11221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ResNode->dump(CurDAG); 11231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand errs() << "\n"; 11241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ); 11251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return ResNode; 11261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 11271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 11281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool SystemZDAGToDAGISel:: 11291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSelectInlineAsmMemoryOperand(const SDValue &Op, 11301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand char ConstraintCode, 11311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand std::vector<SDValue> &OutOps) { 11321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(ConstraintCode == 'm' && "Unexpected constraint code"); 11331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Accept addresses with short displacements, which are compatible 11341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // with Q, R, S and T. But keep the index operand for future expansion. 11351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Base, Disp, Index; 11361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!selectBDXAddr(SystemZAddressingMode::FormBD, 11371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode::Disp12Only, 11381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Op, Base, Disp, Index)) 11391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 11401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OutOps.push_back(Base); 11411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OutOps.push_back(Disp); 11421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OutOps.push_back(Index); 11431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 11441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 1145