SystemZISelDAGToDAG.cpp revision 745ca1eed7dc0a056b066f16aea750ce6fa8a530
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 221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandnamespace { 231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Used to build addressing modes. 241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstruct SystemZAddressingMode { 251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // The shape of the address. 261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand enum AddrForm { 271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // base+displacement 281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FormBD, 291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // base+displacement+index for load and store operands 311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FormBDXNormal, 321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // base+displacement+index for load address operands 341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FormBDXLA, 351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // base+displacement+index+ADJDYNALLOC 371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FormBDXDynAlloc 381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand }; 391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand AddrForm Form; 401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // The type of displacement. The enum names here correspond directly 421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // to the definitions in SystemZOperand.td. We could split them into 431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // flags -- single/pair, 128-bit, etc. -- but it hardly seems worth it. 441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand enum DispRange { 451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Disp12Only, 461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Disp12Pair, 471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Disp20Only, 481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Disp20Only128, 491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Disp20Pair 501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand }; 511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DispRange DR; 521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // The parts of the address. The address is equivalent to: 541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // 551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Base + Disp + Index + (IncludesDynAlloc ? ADJDYNALLOC : 0) 561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Base; 571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t Disp; 581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Index; 591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool IncludesDynAlloc; 601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode(AddrForm form, DispRange dr) 621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand : Form(form), DR(dr), Base(), Disp(0), Index(), 631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand IncludesDynAlloc(false) {} 641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // True if the address can have an index register. 661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool hasIndexField() { return Form != FormBD; } 671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // True if the address can (and must) include ADJDYNALLOC. 691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool isDynAlloc() { return Form == FormBDXDynAlloc; } 701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand void dump() { 721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand errs() << "SystemZAddressingMode " << this << '\n'; 731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand errs() << " Base "; 751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Base.getNode() != 0) 761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Base.getNode()->dump(); 771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand errs() << "null\n"; 791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (hasIndexField()) { 811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand errs() << " Index "; 821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Index.getNode() != 0) 831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Index.getNode()->dump(); 841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand errs() << "null\n"; 861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand errs() << " Disp " << Disp; 891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IncludesDynAlloc) 901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand errs() << " + ADJDYNALLOC"; 911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand errs() << '\n'; 921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand}; 941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 95376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford// Return a mask with Count low bits set. 96376452165863fad987c890d9773e6eb87742a3e1Richard Sandifordstatic uint64_t allOnes(unsigned int Count) { 97376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return Count == 0 ? 0 : (uint64_t(1) << (Count - 1) << 1) - 1; 98376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford} 99376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 100722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford// Represents operands 2 to 5 of the ROTATE AND ... SELECTED BITS operation 101722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford// given by Opcode. The operands are: Input (R2), Start (I3), End (I4) and 102722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford// Rotate (I5). The combined operand value is effectively: 103722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford// 104722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford// (or (rotl Input, Rotate), ~Mask) 105722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford// 106722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford// for RNSBG and: 107722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford// 108722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford// (and (rotl Input, Rotate), Mask) 109722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford// 110722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford// otherwise. The value has BitSize bits. 111efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandifordstruct RxSBGOperands { 112722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford RxSBGOperands(unsigned Op, SDValue N) 113722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford : Opcode(Op), BitSize(N.getValueType().getSizeInBits()), 114722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford Mask(allOnes(BitSize)), Input(N), Start(64 - BitSize), End(63), 115722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford Rotate(0) {} 116376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 117722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford unsigned Opcode; 118376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford unsigned BitSize; 119376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford uint64_t Mask; 120376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford SDValue Input; 121376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford unsigned Start; 122376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford unsigned End; 123376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford unsigned Rotate; 124376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford}; 125376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 1261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandclass SystemZDAGToDAGISel : public SelectionDAGISel { 1271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SystemZTargetLowering &Lowering; 1281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SystemZSubtarget &Subtarget; 1291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Used by SystemZOperands.td to create integer constants. 1318dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford inline SDValue getImm(const SDNode *Node, uint64_t Imm) const { 1321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return CurDAG->getTargetConstant(Imm, Node->getValueType(0)); 1331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 135b3f912b510f8040690864126351b7021980558bbRichard Sandiford const SystemZTargetMachine &getTargetMachine() const { 136b3f912b510f8040690864126351b7021980558bbRichard Sandiford return static_cast<const SystemZTargetMachine &>(TM); 137b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 138b3f912b510f8040690864126351b7021980558bbRichard Sandiford 139b3f912b510f8040690864126351b7021980558bbRichard Sandiford const SystemZInstrInfo *getInstrInfo() const { 140b3f912b510f8040690864126351b7021980558bbRichard Sandiford return getTargetMachine().getInstrInfo(); 141b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 142b3f912b510f8040690864126351b7021980558bbRichard Sandiford 1431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Try to fold more of the base or index of AM into AM, where IsBase 1441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // selects between the base and index. 1458dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool expandAddress(SystemZAddressingMode &AM, bool IsBase) const; 1461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Try to describe N in AM, returning true on success. 1488dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool selectAddress(SDValue N, SystemZAddressingMode &AM) const; 1491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Extract individual target operands from matched address AM. 1511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand void getAddressOperands(const SystemZAddressingMode &AM, EVT VT, 1528dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Base, SDValue &Disp) const; 1531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand void getAddressOperands(const SystemZAddressingMode &AM, EVT VT, 1548dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Base, SDValue &Disp, SDValue &Index) const; 1551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Try to match Addr as a FormBD address with displacement type DR. 1571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Return true on success, storing the base and displacement in 1581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Base and Disp respectively. 1591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool selectBDAddr(SystemZAddressingMode::DispRange DR, SDValue Addr, 1608dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Base, SDValue &Disp) const; 1611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16265ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford // Try to match Addr as a FormBDX address with displacement type DR. 16365ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford // Return true on success and if the result had no index. Store the 16465ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford // base and displacement in Base and Disp respectively. 16565ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford bool selectMVIAddr(SystemZAddressingMode::DispRange DR, SDValue Addr, 1668dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Base, SDValue &Disp) const; 16765ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford 1681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Try to match Addr as a FormBDX* address of form Form with 1691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // displacement type DR. Return true on success, storing the base, 1701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // displacement and index in Base, Disp and Index respectively. 1711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool selectBDXAddr(SystemZAddressingMode::AddrForm Form, 1721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode::DispRange DR, SDValue Addr, 1738dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Base, SDValue &Disp, SDValue &Index) const; 1741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // PC-relative address matching routines used by SystemZOperands.td. 1768dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool selectPCRelAddress(SDValue Addr, SDValue &Target) const { 1778dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford if (SystemZISD::isPCREL(Addr.getOpcode())) { 1781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Target = Addr.getOperand(0); 1791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 1801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 1821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // BD matching routines used by SystemZOperands.td. 1858dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool selectBDAddr12Only(SDValue Addr, SDValue &Base, SDValue &Disp) const { 1861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return selectBDAddr(SystemZAddressingMode::Disp12Only, Addr, Base, Disp); 1871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1888dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool selectBDAddr12Pair(SDValue Addr, SDValue &Base, SDValue &Disp) const { 1891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return selectBDAddr(SystemZAddressingMode::Disp12Pair, Addr, Base, Disp); 1901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1918dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool selectBDAddr20Only(SDValue Addr, SDValue &Base, SDValue &Disp) const { 1921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return selectBDAddr(SystemZAddressingMode::Disp20Only, Addr, Base, Disp); 1931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1948dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool selectBDAddr20Pair(SDValue Addr, SDValue &Base, SDValue &Disp) const { 1951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return selectBDAddr(SystemZAddressingMode::Disp20Pair, Addr, Base, Disp); 1961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 19865ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford // MVI matching routines used by SystemZOperands.td. 1998dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool selectMVIAddr12Pair(SDValue Addr, SDValue &Base, SDValue &Disp) const { 20065ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford return selectMVIAddr(SystemZAddressingMode::Disp12Pair, Addr, Base, Disp); 20165ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford } 2028dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool selectMVIAddr20Pair(SDValue Addr, SDValue &Base, SDValue &Disp) const { 20365ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford return selectMVIAddr(SystemZAddressingMode::Disp20Pair, Addr, Base, Disp); 20465ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford } 20565ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford 2061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // BDX matching routines used by SystemZOperands.td. 2071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool selectBDXAddr12Only(SDValue Addr, SDValue &Base, SDValue &Disp, 2088dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Index) const { 2091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return selectBDXAddr(SystemZAddressingMode::FormBDXNormal, 2101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode::Disp12Only, 2111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Addr, Base, Disp, Index); 2121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool selectBDXAddr12Pair(SDValue Addr, SDValue &Base, SDValue &Disp, 2148dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Index) const { 2151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return selectBDXAddr(SystemZAddressingMode::FormBDXNormal, 2161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode::Disp12Pair, 2171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Addr, Base, Disp, Index); 2181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool selectDynAlloc12Only(SDValue Addr, SDValue &Base, SDValue &Disp, 2208dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Index) const { 2211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return selectBDXAddr(SystemZAddressingMode::FormBDXDynAlloc, 2221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode::Disp12Only, 2231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Addr, Base, Disp, Index); 2241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool selectBDXAddr20Only(SDValue Addr, SDValue &Base, SDValue &Disp, 2268dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Index) const { 2271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return selectBDXAddr(SystemZAddressingMode::FormBDXNormal, 2281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode::Disp20Only, 2291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Addr, Base, Disp, Index); 2301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool selectBDXAddr20Only128(SDValue Addr, SDValue &Base, SDValue &Disp, 2328dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Index) const { 2331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return selectBDXAddr(SystemZAddressingMode::FormBDXNormal, 2341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode::Disp20Only128, 2351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Addr, Base, Disp, Index); 2361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool selectBDXAddr20Pair(SDValue Addr, SDValue &Base, SDValue &Disp, 2388dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Index) const { 2391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return selectBDXAddr(SystemZAddressingMode::FormBDXNormal, 2401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode::Disp20Pair, 2411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Addr, Base, Disp, Index); 2421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool selectLAAddr12Pair(SDValue Addr, SDValue &Base, SDValue &Disp, 2448dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Index) const { 2451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return selectBDXAddr(SystemZAddressingMode::FormBDXLA, 2461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode::Disp12Pair, 2471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Addr, Base, Disp, Index); 2481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool selectLAAddr20Pair(SDValue Addr, SDValue &Base, SDValue &Disp, 2508dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Index) const { 2511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return selectBDXAddr(SystemZAddressingMode::FormBDXLA, 2521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode::Disp20Pair, 2531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Addr, Base, Disp, Index); 2541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 256de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // Check whether (or Op (and X InsertMask)) is effectively an insertion 257de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // of X into bits InsertMask of some Y != Op. Return true if so and 258de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // set Op to that Y. 2598dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool detectOrAndInsertion(SDValue &Op, uint64_t InsertMask) const; 260de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford 261b3f912b510f8040690864126351b7021980558bbRichard Sandiford // Try to update RxSBG so that only the bits of RxSBG.Input in Mask are used. 262b3f912b510f8040690864126351b7021980558bbRichard Sandiford // Return true on success. 2638dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool refineRxSBGMask(RxSBGOperands &RxSBG, uint64_t Mask) const; 264b3f912b510f8040690864126351b7021980558bbRichard Sandiford 265efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford // Try to fold some of RxSBG.Input into other fields of RxSBG. 266efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford // Return true on success. 2678dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool expandRxSBG(RxSBGOperands &RxSBG) const; 268376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 269b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford // Return an undefined i64 value. 2708dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue getUNDEF64(SDLoc DL) const; 271b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford 272b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford // Convert N to VT, if it isn't already. 2738dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue convertTo(SDLoc DL, EVT VT, SDValue N) const; 274b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford 275376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford // Try to implement AND or shift node N using RISBG with the zero flag set. 276376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford // Return the selected node on success, otherwise return null. 277376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford SDNode *tryRISBGZero(SDNode *N); 278b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford 27930a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford // Try to use RISBG or Opcode to implement OR or XOR node N. 28030a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford // Return the selected node on success, otherwise return null. 28130a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford SDNode *tryRxSBG(SDNode *N, unsigned Opcode); 282de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford 2831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If Op0 is null, then Node is a constant that can be loaded using: 2841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // 2851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // (Opcode UpperVal LowerVal) 2861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // 2871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If Op0 is nonnull, then Node can be implemented using: 2881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // 2891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // (Opcode (Opcode Op0 UpperVal) LowerVal) 2901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDNode *splitLargeImmediate(unsigned Opcode, SDNode *Node, SDValue Op0, 2911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t UpperVal, uint64_t LowerVal); 2921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2930548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // Return true if Load and Store are loads and stores of the same size 2940548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // and are guaranteed not to overlap. Such operations can be implemented 2950548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // using block (SS-format) instructions. 2960548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // 2970548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // Partial overlap would lead to incorrect code, since the block operations 2980548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // are logically bytewise, even though they have a fast path for the 2990548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // non-overlapping case. We also need to avoid full overlap (i.e. two 3000548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // addresses that might be equal at run time) because although that case 3010548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // would be handled correctly, it might be implemented by millicode. 3020548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford bool canUseBlockOperation(StoreSDNode *Store, LoadSDNode *Load) const; 3030548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford 30416277c4698f36a756c540fae326874774156aaedRichard Sandiford // N is a (store (load Y), X) pattern. Return true if it can use an MVC 30516277c4698f36a756c540fae326874774156aaedRichard Sandiford // from Y to X. 3062e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford bool storeLoadCanUseMVC(SDNode *N) const; 3072e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford 30816277c4698f36a756c540fae326874774156aaedRichard Sandiford // N is a (store (op (load A[0]), (load A[1])), X) pattern. Return true 30916277c4698f36a756c540fae326874774156aaedRichard Sandiford // if A[1 - I] == X and if N can use a block operation like NC from A[I] 31016277c4698f36a756c540fae326874774156aaedRichard Sandiford // to X. 31116277c4698f36a756c540fae326874774156aaedRichard Sandiford bool storeLoadCanUseBlockBinary(SDNode *N, unsigned I) const; 31216277c4698f36a756c540fae326874774156aaedRichard Sandiford 3131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandpublic: 3141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZDAGToDAGISel(SystemZTargetMachine &TM, CodeGenOpt::Level OptLevel) 3151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand : SelectionDAGISel(TM, OptLevel), 3161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Lowering(*TM.getTargetLowering()), 3171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Subtarget(*TM.getSubtargetImpl()) { } 3181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Override MachineFunctionPass. 3201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand virtual const char *getPassName() const LLVM_OVERRIDE { 3211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return "SystemZ DAG->DAG Pattern Instruction Selection"; 3221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Override SelectionDAGISel. 3251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand virtual SDNode *Select(SDNode *Node) LLVM_OVERRIDE; 3261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, 3271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand char ConstraintCode, 3281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand std::vector<SDValue> &OutOps) 3291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LLVM_OVERRIDE; 3301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Include the pieces autogenerated from the target description. 3321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand #include "SystemZGenDAGISel.inc" 3331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand}; 3341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} // end anonymous namespace 3351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandFunctionPass *llvm::createSystemZISelDag(SystemZTargetMachine &TM, 3371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CodeGenOpt::Level OptLevel) { 3381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return new SystemZDAGToDAGISel(TM, OptLevel); 3391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Return true if Val should be selected as a displacement for an address 3421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// with range DR. Here we're interested in the range of both the instruction 3431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// described by DR and of any pairing instruction. 3441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic bool selectDisp(SystemZAddressingMode::DispRange DR, int64_t Val) { 3451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (DR) { 3461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZAddressingMode::Disp12Only: 3471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return isUInt<12>(Val); 3481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZAddressingMode::Disp12Pair: 3501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZAddressingMode::Disp20Only: 3511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZAddressingMode::Disp20Pair: 3521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return isInt<20>(Val); 3531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZAddressingMode::Disp20Only128: 3551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return isInt<20>(Val) && isInt<20>(Val + 8); 3561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Unhandled displacement range"); 3581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Change the base or index in AM to Value, where IsBase selects 3611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// between the base and index. 3621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic void changeComponent(SystemZAddressingMode &AM, bool IsBase, 3631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Value) { 3641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsBase) 3651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand AM.Base = Value; 3661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 3671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand AM.Index = Value; 3681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// The base or index of AM is equivalent to Value + ADJDYNALLOC, 3711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// where IsBase selects between the base and index. Try to fold the 3721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// ADJDYNALLOC into AM. 3731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic bool expandAdjDynAlloc(SystemZAddressingMode &AM, bool IsBase, 3741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Value) { 3751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (AM.isDynAlloc() && !AM.IncludesDynAlloc) { 3761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand changeComponent(AM, IsBase, Value); 3771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand AM.IncludesDynAlloc = true; 3781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 3791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 3811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// The base of AM is equivalent to Base + Index. Try to use Index as 3841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// the index register. 3851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic bool expandIndex(SystemZAddressingMode &AM, SDValue Base, 3861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Index) { 3871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (AM.hasIndexField() && !AM.Index.getNode()) { 3881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand AM.Base = Base; 3891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand AM.Index = Index; 3901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 3911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 3931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// The base or index of AM is equivalent to Op0 + Op1, where IsBase selects 3961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// between the base and index. Try to fold Op1 into AM's displacement. 3971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic bool expandDisp(SystemZAddressingMode &AM, bool IsBase, 3988dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue Op0, uint64_t Op1) { 3991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // First try adjusting the displacement. 4008dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford int64_t TestDisp = AM.Disp + Op1; 4011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (selectDisp(AM.DR, TestDisp)) { 4021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand changeComponent(AM, IsBase, Op0); 4031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand AM.Disp = TestDisp; 4041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 4051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 4061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We could consider forcing the displacement into a register and 4081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // using it as an index, but it would need to be carefully tuned. 4091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 4101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 4111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool SystemZDAGToDAGISel::expandAddress(SystemZAddressingMode &AM, 4138dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford bool IsBase) const { 4141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue N = IsBase ? AM.Base : AM.Index; 4151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Opcode = N.getOpcode(); 4161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Opcode == ISD::TRUNCATE) { 4171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand N = N.getOperand(0); 4181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = N.getOpcode(); 4191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 4201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Opcode == ISD::ADD || CurDAG->isBaseWithConstantOffset(N)) { 4211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Op0 = N.getOperand(0); 4221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Op1 = N.getOperand(1); 4231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Op0Code = Op0->getOpcode(); 4251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Op1Code = Op1->getOpcode(); 4261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Op0Code == SystemZISD::ADJDYNALLOC) 4281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return expandAdjDynAlloc(AM, IsBase, Op1); 4291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Op1Code == SystemZISD::ADJDYNALLOC) 4301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return expandAdjDynAlloc(AM, IsBase, Op0); 4311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Op0Code == ISD::Constant) 4338dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford return expandDisp(AM, IsBase, Op1, 4348dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford cast<ConstantSDNode>(Op0)->getSExtValue()); 4351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Op1Code == ISD::Constant) 4368dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford return expandDisp(AM, IsBase, Op0, 4378dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford cast<ConstantSDNode>(Op1)->getSExtValue()); 4381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsBase && expandIndex(AM, Op0, Op1)) 4401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 4411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 4428dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford if (Opcode == SystemZISD::PCREL_OFFSET) { 4438dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue Full = N.getOperand(0); 4448dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue Base = N.getOperand(1); 4458dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue Anchor = Base.getOperand(0); 4468dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford uint64_t Offset = (cast<GlobalAddressSDNode>(Full)->getOffset() - 4478dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford cast<GlobalAddressSDNode>(Anchor)->getOffset()); 4488dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford return expandDisp(AM, IsBase, Base, Offset); 4498dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford } 4501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 4511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 4521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Return true if an instruction with displacement range DR should be 4541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// used for displacement value Val. selectDisp(DR, Val) must already hold. 4551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic bool isValidDisp(SystemZAddressingMode::DispRange DR, int64_t Val) { 4561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(selectDisp(DR, Val) && "Invalid displacement"); 4571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (DR) { 4581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZAddressingMode::Disp12Only: 4591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZAddressingMode::Disp20Only: 4601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZAddressingMode::Disp20Only128: 4611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 4621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZAddressingMode::Disp12Pair: 4641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Use the other instruction if the displacement is too large. 4651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return isUInt<12>(Val); 4661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZAddressingMode::Disp20Pair: 4681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Use the other instruction if the displacement is small enough. 4691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return !isUInt<12>(Val); 4701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 4711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Unhandled displacement range"); 4721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 4731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Return true if Base + Disp + Index should be performed by LA(Y). 4751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic bool shouldUseLA(SDNode *Base, int64_t Disp, SDNode *Index) { 4761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Don't use LA(Y) for constants. 4771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!Base) 4781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 4791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Always use LA(Y) for frame addresses, since we know that the destination 4811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // register is almost always (perhaps always) going to be different from 4821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // the frame register. 4831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Base->getOpcode() == ISD::FrameIndex) 4841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 4851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Disp) { 4871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Always use LA(Y) if there is a base, displacement and index. 4881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Index) 4891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 4901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Always use LA if the displacement is small enough. It should always 4921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // be no worse than AGHI (and better if it avoids a move). 4931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isUInt<12>(Disp)) 4941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 4951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // For similar reasons, always use LAY if the constant is too big for AGHI. 4971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // LAY should be no worse than AGFI. 4981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!isInt<16>(Disp)) 4991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 5001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else { 5011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Don't use LA for plain registers. 5021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!Index) 5031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 5041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Don't use LA for plain addition if the index operand is only used 5061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // once. It should be a natural two-operand addition in that case. 5071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Index->hasOneUse()) 5081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 5091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Prefer addition if the second operation is sign-extended, in the 5111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // hope of using AGF. 5121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned IndexOpcode = Index->getOpcode(); 5131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IndexOpcode == ISD::SIGN_EXTEND || 5141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand IndexOpcode == ISD::SIGN_EXTEND_INREG) 5151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 5161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 5171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Don't use LA for two-operand addition if either operand is only 5191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // used once. The addition instructions are better in that case. 5201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Base->hasOneUse()) 5211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 5221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 5241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 5251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Return true if Addr is suitable for AM, updating AM if so. 5271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool SystemZDAGToDAGISel::selectAddress(SDValue Addr, 5288dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SystemZAddressingMode &AM) const { 5291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Start out assuming that the address will need to be loaded separately, 5301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // then try to extend it as much as we can. 5311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand AM.Base = Addr; 5321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // First try treating the address as a constant. 5341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Addr.getOpcode() == ISD::Constant && 5358dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford expandDisp(AM, true, SDValue(), 5368dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford cast<ConstantSDNode>(Addr)->getSExtValue())) 5371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ; 5381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 5391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Otherwise try expanding each component. 5401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand while (expandAddress(AM, true) || 5411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand (AM.Index.getNode() && expandAddress(AM, false))) 5421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 5431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Reject cases where it isn't profitable to use LA(Y). 5451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (AM.Form == SystemZAddressingMode::FormBDXLA && 5461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand !shouldUseLA(AM.Base.getNode(), AM.Disp, AM.Index.getNode())) 5471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 5481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Reject cases where the other instruction in a pair should be used. 5501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!isValidDisp(AM.DR, AM.Disp)) 5511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 5521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Make sure that ADJDYNALLOC is included where necessary. 5541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (AM.isDynAlloc() && !AM.IncludesDynAlloc) 5551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 5561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DEBUG(AM.dump()); 5581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 5591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 5601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Insert a node into the DAG at least before Pos. This will reposition 5621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// the node as needed, and will assign it a node ID that is <= Pos's ID. 5631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Note that this does *not* preserve the uniqueness of node IDs! 5641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// The selection DAG must no longer depend on their uniqueness when this 5651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// function is used. 5661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic void insertDAGNode(SelectionDAG *DAG, SDNode *Pos, SDValue N) { 5671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (N.getNode()->getNodeId() == -1 || 5681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand N.getNode()->getNodeId() > Pos->getNodeId()) { 5691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG->RepositionNode(Pos, N.getNode()); 5701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand N.getNode()->setNodeId(Pos->getNodeId()); 5711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 5721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 5731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZDAGToDAGISel::getAddressOperands(const SystemZAddressingMode &AM, 5751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT VT, SDValue &Base, 5768dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Disp) const { 5771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Base = AM.Base; 5781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!Base.getNode()) 5791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Register 0 means "no base". This is mostly useful for shifts. 5801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Base = CurDAG->getRegister(0, VT); 5811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (Base.getOpcode() == ISD::FrameIndex) { 5821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Lower a FrameIndex to a TargetFrameIndex. 5831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t FrameIndex = cast<FrameIndexSDNode>(Base)->getIndex(); 5841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Base = CurDAG->getTargetFrameIndex(FrameIndex, VT); 5851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (Base.getValueType() != VT) { 5861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Truncate values from i64 to i32, for shifts. 5871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(VT == MVT::i32 && Base.getValueType() == MVT::i64 && 5881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand "Unexpected truncation"); 589ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Base); 5901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Trunc = CurDAG->getNode(ISD::TRUNCATE, DL, VT, Base); 5911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand insertDAGNode(CurDAG, Base.getNode(), Trunc); 5921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Base = Trunc; 5931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 5941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Lower the displacement to a TargetConstant. 5961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Disp = CurDAG->getTargetConstant(AM.Disp, VT); 5971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 5981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZDAGToDAGISel::getAddressOperands(const SystemZAddressingMode &AM, 6001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT VT, SDValue &Base, 6018dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Disp, 6028dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Index) const { 6031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand getAddressOperands(AM, VT, Base, Disp); 6041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Index = AM.Index; 6061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!Index.getNode()) 6071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Register 0 means "no index". 6081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Index = CurDAG->getRegister(0, VT); 6091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 6101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool SystemZDAGToDAGISel::selectBDAddr(SystemZAddressingMode::DispRange DR, 6121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Addr, SDValue &Base, 6138dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Disp) const { 6141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode AM(SystemZAddressingMode::FormBD, DR); 6151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!selectAddress(Addr, AM)) 6161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 6171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand getAddressOperands(AM, Addr.getValueType(), Base, Disp); 6191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 6201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 6211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 62265ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandifordbool SystemZDAGToDAGISel::selectMVIAddr(SystemZAddressingMode::DispRange DR, 62365ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford SDValue Addr, SDValue &Base, 6248dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Disp) const { 62565ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford SystemZAddressingMode AM(SystemZAddressingMode::FormBDXNormal, DR); 62665ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford if (!selectAddress(Addr, AM) || AM.Index.getNode()) 62765ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford return false; 62865ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford 62965ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford getAddressOperands(AM, Addr.getValueType(), Base, Disp); 63065ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford return true; 63165ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford} 63265ddcfa8c1c05aeecd9d4fb062bb121e376aacebRichard Sandiford 6331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool SystemZDAGToDAGISel::selectBDXAddr(SystemZAddressingMode::AddrForm Form, 6341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode::DispRange DR, 6351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Addr, SDValue &Base, 6368dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue &Disp, SDValue &Index) const { 6371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode AM(Form, DR); 6381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!selectAddress(Addr, AM)) 6391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 6401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand getAddressOperands(AM, Addr.getValueType(), Base, Disp, Index); 6421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 6431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 6441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 645de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandifordbool SystemZDAGToDAGISel::detectOrAndInsertion(SDValue &Op, 6468dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford uint64_t InsertMask) const { 647de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // We're only interested in cases where the insertion is into some operand 648de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // of Op, rather than into Op itself. The only useful case is an AND. 649de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford if (Op.getOpcode() != ISD::AND) 650de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford return false; 651de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford 652de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // We need a constant mask. 653de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford ConstantSDNode *MaskNode = 654de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford 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; 668de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford CurDAG->ComputeMaskedBits(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 6909dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford// RxSBG.Input is a shift of Count bits in the direction given by IsLeft. 6919dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford// Return true if the result depends on the signs or zeros that are 6929dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford// shifted in. 6939dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandifordstatic bool shiftedInBitsMatter(RxSBGOperands &RxSBG, uint64_t Count, 6949dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford bool IsLeft) { 6959dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford // Work out which bits of the shift result are zeros or sign copies. 6969dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford uint64_t ShiftedIn = allOnes(Count); 6979dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford if (!IsLeft) 6989dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford ShiftedIn <<= RxSBG.BitSize - Count; 6999dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford 7009dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford // Rotate that mask in the same way as RxSBG.Input is rotated. 7019dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford if (RxSBG.Rotate != 0) 7029dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford ShiftedIn = ((ShiftedIn << RxSBG.Rotate) | 7039dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford (ShiftedIn >> (64 - RxSBG.Rotate))); 7049dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford 7059dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford // Fail if any of the zero or sign bits are used. 7069dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford return (ShiftedIn & RxSBG.Mask) != 0; 7079dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford} 7089dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford 7098dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandifordbool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG) const { 710efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford SDValue N = RxSBG.Input; 7119dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford unsigned Opcode = N.getOpcode(); 7129dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford switch (Opcode) { 713376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford case ISD::AND: { 714722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford if (RxSBG.Opcode == SystemZ::RNSBG) 715722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford return false; 716722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford 717376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford ConstantSDNode *MaskNode = 718376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford dyn_cast<ConstantSDNode>(N.getOperand(1).getNode()); 719376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford if (!MaskNode) 720376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return false; 721376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 722376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford SDValue Input = N.getOperand(0); 723376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford uint64_t Mask = MaskNode->getZExtValue(); 724efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford if (!refineRxSBGMask(RxSBG, Mask)) { 725376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford // If some bits of Input are already known zeros, those bits will have 726376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford // been removed from the mask. See if adding them back in makes the 727376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford // mask suitable. 728376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford APInt KnownZero, KnownOne; 729376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford CurDAG->ComputeMaskedBits(Input, KnownZero, KnownOne); 730376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford Mask |= KnownZero.getZExtValue(); 731efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford if (!refineRxSBGMask(RxSBG, Mask)) 732376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return false; 733376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford } 734efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford RxSBG.Input = Input; 735376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return true; 736376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford } 737376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 738722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford case ISD::OR: { 739722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford if (RxSBG.Opcode != SystemZ::RNSBG) 740722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford return false; 741722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford 742722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford ConstantSDNode *MaskNode = 743722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford dyn_cast<ConstantSDNode>(N.getOperand(1).getNode()); 744722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford if (!MaskNode) 745722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford return false; 746722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford 747722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford SDValue Input = N.getOperand(0); 748722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford uint64_t Mask = ~MaskNode->getZExtValue(); 749722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford if (!refineRxSBGMask(RxSBG, Mask)) { 750722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford // If some bits of Input are already known ones, those bits will have 751722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford // been removed from the mask. See if adding them back in makes the 752722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford // mask suitable. 753722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford APInt KnownZero, KnownOne; 754722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford CurDAG->ComputeMaskedBits(Input, KnownZero, KnownOne); 755722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford Mask &= ~KnownOne.getZExtValue(); 756722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford if (!refineRxSBGMask(RxSBG, Mask)) 757722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford return false; 758722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford } 759722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford RxSBG.Input = Input; 760722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford return true; 761722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford } 762722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford 763376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford case ISD::ROTL: { 764efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford // Any 64-bit rotate left can be merged into the RxSBG. 765efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford if (RxSBG.BitSize != 64) 766376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return false; 767376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford ConstantSDNode *CountNode 768376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford = dyn_cast<ConstantSDNode>(N.getOperand(1).getNode()); 769376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford if (!CountNode) 770376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return false; 771376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 772efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford RxSBG.Rotate = (RxSBG.Rotate + CountNode->getZExtValue()) & 63; 773efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford RxSBG.Input = N.getOperand(0); 774376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return true; 775376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford } 776376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 777376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford case ISD::SHL: { 778376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford ConstantSDNode *CountNode = 779376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford dyn_cast<ConstantSDNode>(N.getOperand(1).getNode()); 780376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford if (!CountNode) 781376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return false; 782376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 783376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford uint64_t Count = CountNode->getZExtValue(); 784722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford if (Count < 1 || Count >= RxSBG.BitSize) 785376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return false; 786376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 787722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford if (RxSBG.Opcode == SystemZ::RNSBG) { 788722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford // Treat (shl X, count) as (rotl X, size-count) as long as the bottom 789722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford // count bits from RxSBG.Input are ignored. 790722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford if (shiftedInBitsMatter(RxSBG, Count, true)) 791722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford return false; 792722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford } else { 793722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford // Treat (shl X, count) as (and (rotl X, count), ~0<<count). 794722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford if (!refineRxSBGMask(RxSBG, allOnes(RxSBG.BitSize - Count) << Count)) 795722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford return false; 796722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford } 797722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford 798efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford RxSBG.Rotate = (RxSBG.Rotate + Count) & 63; 799efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford RxSBG.Input = N.getOperand(0); 800376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return true; 801376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford } 802376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 8039dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford case ISD::SRL: 804376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford case ISD::SRA: { 805376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford ConstantSDNode *CountNode = 806376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford dyn_cast<ConstantSDNode>(N.getOperand(1).getNode()); 807376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford if (!CountNode) 808376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return false; 809376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 810376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford uint64_t Count = CountNode->getZExtValue(); 8119dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford if (Count < 1 || Count >= RxSBG.BitSize) 812376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return false; 813376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 814722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford if (RxSBG.Opcode == SystemZ::RNSBG || Opcode == ISD::SRA) { 815722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford // Treat (srl|sra X, count) as (rotl X, size-count) as long as the top 816722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford // count bits from RxSBG.Input are ignored. 8179dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford if (shiftedInBitsMatter(RxSBG, Count, false)) 8189dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford return false; 8199dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford } else { 8209dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford // Treat (srl X, count), mask) as (and (rotl X, size-count), ~0>>count), 8219dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford // which is similar to SLL above. 8229dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford if (!refineRxSBGMask(RxSBG, allOnes(RxSBG.BitSize - Count))) 8239dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford return false; 8249dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford } 8259dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford 8269dffd71d0af3d78ee1f21865dd064fb43bc623beRichard Sandiford RxSBG.Rotate = (RxSBG.Rotate - Count) & 63; 827efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford RxSBG.Input = N.getOperand(0); 828376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return true; 829376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford } 830376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford default: 831376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford return false; 832376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford } 833376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford} 834376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford 8358dac19c0708c9bd0da0b832014918e00ded44d86Richard SandifordSDValue SystemZDAGToDAGISel::getUNDEF64(SDLoc DL) const { 836b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford SDNode *N = CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MVT::i64); 837b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford return SDValue(N, 0); 838b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford} 839b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford 8408dac19c0708c9bd0da0b832014918e00ded44d86Richard SandifordSDValue SystemZDAGToDAGISel::convertTo(SDLoc DL, EVT VT, SDValue N) const { 8417c7b431d2fa3ead0a2a24c4dd81fc92f293203ddRichard Sandiford if (N.getValueType() == MVT::i32 && VT == MVT::i64) 842745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford return CurDAG->getTargetInsertSubreg(SystemZ::subreg_l32, 8437c7b431d2fa3ead0a2a24c4dd81fc92f293203ddRichard Sandiford DL, VT, getUNDEF64(DL), N); 8447c7b431d2fa3ead0a2a24c4dd81fc92f293203ddRichard Sandiford if (N.getValueType() == MVT::i64 && VT == MVT::i32) 845745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford return CurDAG->getTargetExtractSubreg(SystemZ::subreg_l32, DL, VT, N); 846b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford assert(N.getValueType() == VT && "Unexpected value types"); 847b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford return N; 848b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford} 849b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford 850376452165863fad987c890d9773e6eb87742a3e1Richard SandifordSDNode *SystemZDAGToDAGISel::tryRISBGZero(SDNode *N) { 851b3f912b510f8040690864126351b7021980558bbRichard Sandiford EVT VT = N->getValueType(0); 852722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford RxSBGOperands RISBG(SystemZ::RISBG, SDValue(N, 0)); 853376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford unsigned Count = 0; 854efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford while (expandRxSBG(RISBG)) 855376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford Count += 1; 856b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (Count == 0) 857b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford return 0; 858b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (Count == 1) { 859b3f912b510f8040690864126351b7021980558bbRichard Sandiford // Prefer to use normal shift instructions over RISBG, since they can handle 860b3f912b510f8040690864126351b7021980558bbRichard Sandiford // all cases and are sometimes shorter. 861b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (N->getOpcode() != ISD::AND) 862b3f912b510f8040690864126351b7021980558bbRichard Sandiford return 0; 863b3f912b510f8040690864126351b7021980558bbRichard Sandiford 864b3f912b510f8040690864126351b7021980558bbRichard Sandiford // Prefer register extensions like LLC over RISBG. Also prefer to start 865b3f912b510f8040690864126351b7021980558bbRichard Sandiford // out with normal ANDs if one instruction would be enough. We can convert 866b3f912b510f8040690864126351b7021980558bbRichard Sandiford // these ANDs into an RISBG later if a three-address instruction is useful. 867b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (VT == MVT::i32 || 868b3f912b510f8040690864126351b7021980558bbRichard Sandiford RISBG.Mask == 0xff || 869b3f912b510f8040690864126351b7021980558bbRichard Sandiford RISBG.Mask == 0xffff || 870b3f912b510f8040690864126351b7021980558bbRichard Sandiford SystemZ::isImmLF(~RISBG.Mask) || 871b3f912b510f8040690864126351b7021980558bbRichard Sandiford SystemZ::isImmHF(~RISBG.Mask)) { 872b3f912b510f8040690864126351b7021980558bbRichard Sandiford // Force the new mask into the DAG, since it may include known-one bits. 873b3f912b510f8040690864126351b7021980558bbRichard Sandiford ConstantSDNode *MaskN = cast<ConstantSDNode>(N->getOperand(1).getNode()); 874b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (MaskN->getZExtValue() != RISBG.Mask) { 875b3f912b510f8040690864126351b7021980558bbRichard Sandiford SDValue NewMask = CurDAG->getConstant(RISBG.Mask, VT); 876b3f912b510f8040690864126351b7021980558bbRichard Sandiford N = CurDAG->UpdateNodeOperands(N, N->getOperand(0), NewMask); 877b3f912b510f8040690864126351b7021980558bbRichard Sandiford return SelectCode(N); 878b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 879b3f912b510f8040690864126351b7021980558bbRichard Sandiford return 0; 880b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 881b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 882b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford 883b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford SDValue Ops[5] = { 884b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford getUNDEF64(SDLoc(N)), 885376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford convertTo(SDLoc(N), MVT::i64, RISBG.Input), 886376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford CurDAG->getTargetConstant(RISBG.Start, MVT::i32), 887376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford CurDAG->getTargetConstant(RISBG.End | 128, MVT::i32), 888376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford CurDAG->getTargetConstant(RISBG.Rotate, MVT::i32) 889b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford }; 890b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford N = CurDAG->getMachineNode(SystemZ::RISBG, SDLoc(N), MVT::i64, Ops); 891b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford return convertTo(SDLoc(N), VT, SDValue(N, 0)).getNode(); 892b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford} 893b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford 89430a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard SandifordSDNode *SystemZDAGToDAGISel::tryRxSBG(SDNode *N, unsigned Opcode) { 89530a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford // Try treating each operand of N as the second operand of the RxSBG 896de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // and see which goes deepest. 897722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford RxSBGOperands RxSBG[] = { 898722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford RxSBGOperands(Opcode, N->getOperand(0)), 899722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford RxSBGOperands(Opcode, N->getOperand(1)) 900722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford }; 901de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford unsigned Count[] = { 0, 0 }; 902de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford for (unsigned I = 0; I < 2; ++I) 903efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford while (expandRxSBG(RxSBG[I])) 904de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford Count[I] += 1; 905de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford 906de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // Do nothing if neither operand is suitable. 907de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford if (Count[0] == 0 && Count[1] == 0) 908de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford return 0; 909de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford 910de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // Pick the deepest second operand. 911de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford unsigned I = Count[0] > Count[1] ? 0 : 1; 912de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford SDValue Op0 = N->getOperand(I ^ 1); 913de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford 914de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // Prefer IC for character insertions from memory. 91530a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford if (Opcode == SystemZ::ROSBG && (RxSBG[I].Mask & 0xff) == 0) 916de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford if (LoadSDNode *Load = dyn_cast<LoadSDNode>(Op0.getNode())) 917de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford if (Load->getMemoryVT() == MVT::i8) 918de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford return 0; 919de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford 920de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // See whether we can avoid an AND in the first operand by converting 921de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford // ROSBG to RISBG. 92230a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford if (Opcode == SystemZ::ROSBG && detectOrAndInsertion(Op0, RxSBG[I].Mask)) 923de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford Opcode = SystemZ::RISBG; 924de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford 925de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford EVT VT = N->getValueType(0); 926de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford SDValue Ops[5] = { 927de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford convertTo(SDLoc(N), MVT::i64, Op0), 928efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford convertTo(SDLoc(N), MVT::i64, RxSBG[I].Input), 929efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford CurDAG->getTargetConstant(RxSBG[I].Start, MVT::i32), 930efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford CurDAG->getTargetConstant(RxSBG[I].End, MVT::i32), 931efb6c52efb4116b6a6d6c99192db68ab69025119Richard Sandiford CurDAG->getTargetConstant(RxSBG[I].Rotate, MVT::i32) 932de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford }; 933de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford N = CurDAG->getMachineNode(Opcode, SDLoc(N), MVT::i64, Ops); 934de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford return convertTo(SDLoc(N), VT, SDValue(N, 0)).getNode(); 935de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford} 936de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford 9371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDNode *SystemZDAGToDAGISel::splitLargeImmediate(unsigned Opcode, SDNode *Node, 9381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Op0, uint64_t UpperVal, 9391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t LowerVal) { 9401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT VT = Node->getValueType(0); 941ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Node); 9421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Upper = CurDAG->getConstant(UpperVal, VT); 9431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Op0.getNode()) 9441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Upper = CurDAG->getNode(Opcode, DL, VT, Op0, Upper); 9451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Upper = SDValue(Select(Upper.getNode()), 0); 9461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Lower = CurDAG->getConstant(LowerVal, VT); 9481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Or = CurDAG->getNode(Opcode, DL, VT, Upper, Lower); 9491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Or.getNode(); 9501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 9511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9520548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandifordbool SystemZDAGToDAGISel::canUseBlockOperation(StoreSDNode *Store, 9530548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford LoadSDNode *Load) const { 95416277c4698f36a756c540fae326874774156aaedRichard Sandiford // Check that the two memory operands have the same size. 95516277c4698f36a756c540fae326874774156aaedRichard Sandiford if (Load->getMemoryVT() != Store->getMemoryVT()) 95616277c4698f36a756c540fae326874774156aaedRichard Sandiford return false; 9572e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford 95816277c4698f36a756c540fae326874774156aaedRichard Sandiford // Volatility stops an access from being decomposed. 9592e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford if (Load->isVolatile() || Store->isVolatile()) 9602e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford return false; 9612e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford 9622e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford // There's no chance of overlap if the load is invariant. 9632e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford if (Load->isInvariant()) 9642e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford return true; 9652e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford 9662e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford // Otherwise we need to check whether there's an alias. 9672e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford const Value *V1 = Load->getSrcValue(); 9682e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford const Value *V2 = Store->getSrcValue(); 9692e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford if (!V1 || !V2) 9702e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford return false; 9712e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford 9720548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // Reject equality. 9730548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford uint64_t Size = Load->getMemoryVT().getStoreSize(); 9742e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford int64_t End1 = Load->getSrcValueOffset() + Size; 9752e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford int64_t End2 = Store->getSrcValueOffset() + Size; 9760548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford if (V1 == V2 && End1 == End2) 9770548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford return false; 9780548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford 9792e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford return !AA->alias(AliasAnalysis::Location(V1, End1, Load->getTBAAInfo()), 9802e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford AliasAnalysis::Location(V2, End2, Store->getTBAAInfo())); 9812e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford} 9822e015ef9bb40e5d9f98db9a9509b9986873089eaRichard Sandiford 98316277c4698f36a756c540fae326874774156aaedRichard Sandifordbool SystemZDAGToDAGISel::storeLoadCanUseMVC(SDNode *N) const { 98416277c4698f36a756c540fae326874774156aaedRichard Sandiford StoreSDNode *Store = cast<StoreSDNode>(N); 98516277c4698f36a756c540fae326874774156aaedRichard Sandiford LoadSDNode *Load = cast<LoadSDNode>(Store->getValue()); 98616277c4698f36a756c540fae326874774156aaedRichard Sandiford 98716277c4698f36a756c540fae326874774156aaedRichard Sandiford // Prefer not to use MVC if either address can use ... RELATIVE LONG 98816277c4698f36a756c540fae326874774156aaedRichard Sandiford // instructions. 98916277c4698f36a756c540fae326874774156aaedRichard Sandiford uint64_t Size = Load->getMemoryVT().getStoreSize(); 99016277c4698f36a756c540fae326874774156aaedRichard Sandiford if (Size > 1 && Size <= 8) { 99116277c4698f36a756c540fae326874774156aaedRichard Sandiford // Prefer LHRL, LRL and LGRL. 9928dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford if (SystemZISD::isPCREL(Load->getBasePtr().getOpcode())) 99316277c4698f36a756c540fae326874774156aaedRichard Sandiford return false; 99416277c4698f36a756c540fae326874774156aaedRichard Sandiford // Prefer STHRL, STRL and STGRL. 9958dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford if (SystemZISD::isPCREL(Store->getBasePtr().getOpcode())) 99616277c4698f36a756c540fae326874774156aaedRichard Sandiford return false; 99716277c4698f36a756c540fae326874774156aaedRichard Sandiford } 99816277c4698f36a756c540fae326874774156aaedRichard Sandiford 9990548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford return canUseBlockOperation(Store, Load); 100016277c4698f36a756c540fae326874774156aaedRichard Sandiford} 100116277c4698f36a756c540fae326874774156aaedRichard Sandiford 100216277c4698f36a756c540fae326874774156aaedRichard Sandifordbool SystemZDAGToDAGISel::storeLoadCanUseBlockBinary(SDNode *N, 100316277c4698f36a756c540fae326874774156aaedRichard Sandiford unsigned I) const { 100416277c4698f36a756c540fae326874774156aaedRichard Sandiford StoreSDNode *StoreA = cast<StoreSDNode>(N); 100516277c4698f36a756c540fae326874774156aaedRichard Sandiford LoadSDNode *LoadA = cast<LoadSDNode>(StoreA->getValue().getOperand(1 - I)); 100616277c4698f36a756c540fae326874774156aaedRichard Sandiford LoadSDNode *LoadB = cast<LoadSDNode>(StoreA->getValue().getOperand(I)); 10070548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford return !LoadA->isVolatile() && canUseBlockOperation(StoreA, LoadB); 100816277c4698f36a756c540fae326874774156aaedRichard Sandiford} 100916277c4698f36a756c540fae326874774156aaedRichard Sandiford 10101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDNode *SystemZDAGToDAGISel::Select(SDNode *Node) { 10111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Dump information about the Node being selected 10121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DEBUG(errs() << "Selecting: "; Node->dump(CurDAG); errs() << "\n"); 10131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 10141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If we have a custom node, we already have selected! 10151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Node->isMachineOpcode()) { 10161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n"); 10173e84ad28d4d3ceee25771b1e30315c20b7608c39Tim Northover Node->setNodeId(-1); 10181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return 0; 10191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 10201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 10211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Opcode = Node->getOpcode(); 1022b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford SDNode *ResNode = 0; 10231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (Opcode) { 10241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::OR: 1025de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford if (Node->getOperand(1).getOpcode() != ISD::Constant) 102630a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford ResNode = tryRxSBG(Node, SystemZ::ROSBG); 102730a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford goto or_xor; 102830a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford 10291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::XOR: 103030a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford if (Node->getOperand(1).getOpcode() != ISD::Constant) 103130a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford ResNode = tryRxSBG(Node, SystemZ::RXSBG); 103230a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford // Fall through. 103330a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford or_xor: 10341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If this is a 64-bit operation in which both 32-bit halves are nonzero, 10351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // split the operation into two. 1036de25544a73acbb1dd99c948ccbea81eedcd34bc9Richard Sandiford if (!ResNode && Node->getValueType(0) == MVT::i64) 10371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ConstantSDNode *Op1 = dyn_cast<ConstantSDNode>(Node->getOperand(1))) { 10381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t Val = Op1->getZExtValue(); 10391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!SystemZ::isImmLF(Val) && !SystemZ::isImmHF(Val)) 10401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Node = splitLargeImmediate(Opcode, Node, Node->getOperand(0), 10411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Val - uint32_t(Val), uint32_t(Val)); 10421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 10431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 10441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1045b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford case ISD::AND: 1046722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford if (Node->getOperand(1).getOpcode() != ISD::Constant) 1047722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford ResNode = tryRxSBG(Node, SystemZ::RNSBG); 1048722a26d63e717f5cfbf924e042f4f300bfee1328Richard Sandiford // Fall through. 1049376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford case ISD::ROTL: 1050376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford case ISD::SHL: 1051376452165863fad987c890d9773e6eb87742a3e1Richard Sandiford case ISD::SRL: 105230a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford if (!ResNode) 105330a132f7676ec5465a2245cb94e7bd9214ea8eb7Richard Sandiford ResNode = tryRISBGZero(Node); 1054b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford break; 1055b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford 10561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::Constant: 10571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If this is a 64-bit constant that is out of the range of LLILF, 10581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // LLIHF and LGFI, split it into two 32-bit pieces. 10591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Node->getValueType(0) == MVT::i64) { 10601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t Val = cast<ConstantSDNode>(Node)->getZExtValue(); 10611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!SystemZ::isImmLF(Val) && !SystemZ::isImmHF(Val) && !isInt<32>(Val)) 10621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Node = splitLargeImmediate(ISD::OR, Node, SDValue(), 10631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Val - uint32_t(Val), uint32_t(Val)); 10641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 10651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 10661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 10671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ATOMIC_LOAD_SUB: 10681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Try to convert subtractions of constants to additions. 10691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ConstantSDNode *Op2 = dyn_cast<ConstantSDNode>(Node->getOperand(2))) { 10701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t Value = -Op2->getZExtValue(); 10711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT VT = Node->getValueType(0); 10721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (VT == MVT::i32 || isInt<32>(Value)) { 10731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Ops[] = { Node->getOperand(0), Node->getOperand(1), 10741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CurDAG->getConstant(int32_t(Value), VT) }; 10751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Node = CurDAG->MorphNodeTo(Node, ISD::ATOMIC_LOAD_ADD, 10761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Node->getVTList(), Ops, array_lengthof(Ops)); 10771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 10781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 10791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 108015715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford 108115715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford case SystemZISD::SELECT_CCMASK: { 108215715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford SDValue Op0 = Node->getOperand(0); 108315715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford SDValue Op1 = Node->getOperand(1); 108415715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford // Prefer to put any load first, so that it can be matched as a 108515715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford // conditional load. 108615715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford if (Op1.getOpcode() == ISD::LOAD && Op0.getOpcode() != ISD::LOAD) { 108715715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford SDValue CCValid = Node->getOperand(2); 108815715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford SDValue CCMask = Node->getOperand(3); 108915715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford uint64_t ConstCCValid = 109015715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford cast<ConstantSDNode>(CCValid.getNode())->getZExtValue(); 109115715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford uint64_t ConstCCMask = 109215715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford cast<ConstantSDNode>(CCMask.getNode())->getZExtValue(); 109315715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford // Invert the condition. 109415715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford CCMask = CurDAG->getConstant(ConstCCValid ^ ConstCCMask, 109515715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford CCMask.getValueType()); 109615715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford SDValue Op4 = Node->getOperand(4); 109715715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford Node = CurDAG->UpdateNodeOperands(Node, Op1, Op0, CCValid, CCMask, Op4); 109815715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford } 109915715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford break; 110015715fb689a5c7a2476c943a7b06616bd6d67d5eRichard Sandiford } 11011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 11021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 11031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Select the default instruction 1104b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford if (!ResNode) 1105b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9Richard Sandiford ResNode = SelectCode(Node); 11061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 11071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DEBUG(errs() << "=> "; 11081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ResNode == NULL || ResNode == Node) 11091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Node->dump(CurDAG); 11101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 11111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ResNode->dump(CurDAG); 11121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand errs() << "\n"; 11131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ); 11141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return ResNode; 11151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 11161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 11171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool SystemZDAGToDAGISel:: 11181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSelectInlineAsmMemoryOperand(const SDValue &Op, 11191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand char ConstraintCode, 11201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand std::vector<SDValue> &OutOps) { 11211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(ConstraintCode == 'm' && "Unexpected constraint code"); 11221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Accept addresses with short displacements, which are compatible 11231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // with Q, R, S and T. But keep the index operand for future expansion. 11241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Base, Disp, Index; 11251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!selectBDXAddr(SystemZAddressingMode::FormBD, 11261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZAddressingMode::Disp12Only, 11271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Op, Base, Disp, Index)) 11281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 11291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OutOps.push_back(Base); 11301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OutOps.push_back(Disp); 11311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OutOps.push_back(Index); 11321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 11331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 1134