LLVM API Documentation

ARMISelDAGToDAG.cpp
Go to the documentation of this file.
00001 //===-- ARMISelDAGToDAG.cpp - A dag to dag inst selector for ARM ----------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines an instruction selector for the ARM target.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "ARM.h"
00015 #include "ARMBaseInstrInfo.h"
00016 #include "ARMTargetMachine.h"
00017 #include "MCTargetDesc/ARMAddressingModes.h"
00018 #include "llvm/CodeGen/MachineFrameInfo.h"
00019 #include "llvm/CodeGen/MachineFunction.h"
00020 #include "llvm/CodeGen/MachineInstrBuilder.h"
00021 #include "llvm/CodeGen/MachineRegisterInfo.h"
00022 #include "llvm/CodeGen/SelectionDAG.h"
00023 #include "llvm/CodeGen/SelectionDAGISel.h"
00024 #include "llvm/IR/CallingConv.h"
00025 #include "llvm/IR/Constants.h"
00026 #include "llvm/IR/DerivedTypes.h"
00027 #include "llvm/IR/Function.h"
00028 #include "llvm/IR/Intrinsics.h"
00029 #include "llvm/IR/LLVMContext.h"
00030 #include "llvm/Support/CommandLine.h"
00031 #include "llvm/Support/Compiler.h"
00032 #include "llvm/Support/Debug.h"
00033 #include "llvm/Support/ErrorHandling.h"
00034 #include "llvm/Target/TargetLowering.h"
00035 #include "llvm/Target/TargetOptions.h"
00036 
00037 using namespace llvm;
00038 
00039 #define DEBUG_TYPE "arm-isel"
00040 
00041 static cl::opt<bool>
00042 DisableShifterOp("disable-shifter-op", cl::Hidden,
00043   cl::desc("Disable isel of shifter-op"),
00044   cl::init(false));
00045 
00046 static cl::opt<bool>
00047 CheckVMLxHazard("check-vmlx-hazard", cl::Hidden,
00048   cl::desc("Check fp vmla / vmls hazard at isel time"),
00049   cl::init(true));
00050 
00051 //===--------------------------------------------------------------------===//
00052 /// ARMDAGToDAGISel - ARM specific code to select ARM machine
00053 /// instructions for SelectionDAG operations.
00054 ///
00055 namespace {
00056 
00057 enum AddrMode2Type {
00058   AM2_BASE, // Simple AM2 (+-imm12)
00059   AM2_SHOP  // Shifter-op AM2
00060 };
00061 
00062 class ARMDAGToDAGISel : public SelectionDAGISel {
00063   /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
00064   /// make the right decision when generating code for different targets.
00065   const ARMSubtarget *Subtarget;
00066 
00067 public:
00068   explicit ARMDAGToDAGISel(ARMBaseTargetMachine &tm, CodeGenOpt::Level OptLevel)
00069       : SelectionDAGISel(tm, OptLevel) {}
00070 
00071   bool runOnMachineFunction(MachineFunction &MF) override {
00072     // Reset the subtarget each time through.
00073     Subtarget = &MF.getTarget().getSubtarget<ARMSubtarget>();
00074     SelectionDAGISel::runOnMachineFunction(MF);
00075     return true;
00076   }
00077 
00078   const char *getPassName() const override {
00079     return "ARM Instruction Selection";
00080   }
00081 
00082   void PreprocessISelDAG() override;
00083 
00084   /// getI32Imm - Return a target constant of type i32 with the specified
00085   /// value.
00086   inline SDValue getI32Imm(unsigned Imm) {
00087     return CurDAG->getTargetConstant(Imm, MVT::i32);
00088   }
00089 
00090   SDNode *Select(SDNode *N) override;
00091 
00092 
00093   bool hasNoVMLxHazardUse(SDNode *N) const;
00094   bool isShifterOpProfitable(const SDValue &Shift,
00095                              ARM_AM::ShiftOpc ShOpcVal, unsigned ShAmt);
00096   bool SelectRegShifterOperand(SDValue N, SDValue &A,
00097                                SDValue &B, SDValue &C,
00098                                bool CheckProfitability = true);
00099   bool SelectImmShifterOperand(SDValue N, SDValue &A,
00100                                SDValue &B, bool CheckProfitability = true);
00101   bool SelectShiftRegShifterOperand(SDValue N, SDValue &A,
00102                                     SDValue &B, SDValue &C) {
00103     // Don't apply the profitability check
00104     return SelectRegShifterOperand(N, A, B, C, false);
00105   }
00106   bool SelectShiftImmShifterOperand(SDValue N, SDValue &A,
00107                                     SDValue &B) {
00108     // Don't apply the profitability check
00109     return SelectImmShifterOperand(N, A, B, false);
00110   }
00111 
00112   bool SelectAddrModeImm12(SDValue N, SDValue &Base, SDValue &OffImm);
00113   bool SelectLdStSOReg(SDValue N, SDValue &Base, SDValue &Offset, SDValue &Opc);
00114 
00115   AddrMode2Type SelectAddrMode2Worker(SDValue N, SDValue &Base,
00116                                       SDValue &Offset, SDValue &Opc);
00117   bool SelectAddrMode2Base(SDValue N, SDValue &Base, SDValue &Offset,
00118                            SDValue &Opc) {
00119     return SelectAddrMode2Worker(N, Base, Offset, Opc) == AM2_BASE;
00120   }
00121 
00122   bool SelectAddrMode2ShOp(SDValue N, SDValue &Base, SDValue &Offset,
00123                            SDValue &Opc) {
00124     return SelectAddrMode2Worker(N, Base, Offset, Opc) == AM2_SHOP;
00125   }
00126 
00127   bool SelectAddrMode2(SDValue N, SDValue &Base, SDValue &Offset,
00128                        SDValue &Opc) {
00129     SelectAddrMode2Worker(N, Base, Offset, Opc);
00130 //    return SelectAddrMode2ShOp(N, Base, Offset, Opc);
00131     // This always matches one way or another.
00132     return true;
00133   }
00134 
00135   bool SelectCMOVPred(SDValue N, SDValue &Pred, SDValue &Reg) {
00136     const ConstantSDNode *CN = cast<ConstantSDNode>(N);
00137     Pred = CurDAG->getTargetConstant(CN->getZExtValue(), MVT::i32);
00138     Reg = CurDAG->getRegister(ARM::CPSR, MVT::i32);
00139     return true;
00140   }
00141 
00142   bool SelectAddrMode2OffsetReg(SDNode *Op, SDValue N,
00143                              SDValue &Offset, SDValue &Opc);
00144   bool SelectAddrMode2OffsetImm(SDNode *Op, SDValue N,
00145                              SDValue &Offset, SDValue &Opc);
00146   bool SelectAddrMode2OffsetImmPre(SDNode *Op, SDValue N,
00147                              SDValue &Offset, SDValue &Opc);
00148   bool SelectAddrOffsetNone(SDValue N, SDValue &Base);
00149   bool SelectAddrMode3(SDValue N, SDValue &Base,
00150                        SDValue &Offset, SDValue &Opc);
00151   bool SelectAddrMode3Offset(SDNode *Op, SDValue N,
00152                              SDValue &Offset, SDValue &Opc);
00153   bool SelectAddrMode5(SDValue N, SDValue &Base,
00154                        SDValue &Offset);
00155   bool SelectAddrMode6(SDNode *Parent, SDValue N, SDValue &Addr,SDValue &Align);
00156   bool SelectAddrMode6Offset(SDNode *Op, SDValue N, SDValue &Offset);
00157 
00158   bool SelectAddrModePC(SDValue N, SDValue &Offset, SDValue &Label);
00159 
00160   // Thumb Addressing Modes:
00161   bool SelectThumbAddrModeRR(SDValue N, SDValue &Base, SDValue &Offset);
00162   bool SelectThumbAddrModeRI(SDValue N, SDValue &Base, SDValue &Offset,
00163                              unsigned Scale);
00164   bool SelectThumbAddrModeRI5S1(SDValue N, SDValue &Base, SDValue &Offset);
00165   bool SelectThumbAddrModeRI5S2(SDValue N, SDValue &Base, SDValue &Offset);
00166   bool SelectThumbAddrModeRI5S4(SDValue N, SDValue &Base, SDValue &Offset);
00167   bool SelectThumbAddrModeImm5S(SDValue N, unsigned Scale, SDValue &Base,
00168                                 SDValue &OffImm);
00169   bool SelectThumbAddrModeImm5S1(SDValue N, SDValue &Base,
00170                                  SDValue &OffImm);
00171   bool SelectThumbAddrModeImm5S2(SDValue N, SDValue &Base,
00172                                  SDValue &OffImm);
00173   bool SelectThumbAddrModeImm5S4(SDValue N, SDValue &Base,
00174                                  SDValue &OffImm);
00175   bool SelectThumbAddrModeSP(SDValue N, SDValue &Base, SDValue &OffImm);
00176 
00177   // Thumb 2 Addressing Modes:
00178   bool SelectT2ShifterOperandReg(SDValue N,
00179                                  SDValue &BaseReg, SDValue &Opc);
00180   bool SelectT2AddrModeImm12(SDValue N, SDValue &Base, SDValue &OffImm);
00181   bool SelectT2AddrModeImm8(SDValue N, SDValue &Base,
00182                             SDValue &OffImm);
00183   bool SelectT2AddrModeImm8Offset(SDNode *Op, SDValue N,
00184                                  SDValue &OffImm);
00185   bool SelectT2AddrModeSoReg(SDValue N, SDValue &Base,
00186                              SDValue &OffReg, SDValue &ShImm);
00187   bool SelectT2AddrModeExclusive(SDValue N, SDValue &Base, SDValue &OffImm);
00188 
00189   inline bool is_so_imm(unsigned Imm) const {
00190     return ARM_AM::getSOImmVal(Imm) != -1;
00191   }
00192 
00193   inline bool is_so_imm_not(unsigned Imm) const {
00194     return ARM_AM::getSOImmVal(~Imm) != -1;
00195   }
00196 
00197   inline bool is_t2_so_imm(unsigned Imm) const {
00198     return ARM_AM::getT2SOImmVal(Imm) != -1;
00199   }
00200 
00201   inline bool is_t2_so_imm_not(unsigned Imm) const {
00202     return ARM_AM::getT2SOImmVal(~Imm) != -1;
00203   }
00204 
00205   // Include the pieces autogenerated from the target description.
00206 #include "ARMGenDAGISel.inc"
00207 
00208 private:
00209   /// SelectARMIndexedLoad - Indexed (pre/post inc/dec) load matching code for
00210   /// ARM.
00211   SDNode *SelectARMIndexedLoad(SDNode *N);
00212   SDNode *SelectT2IndexedLoad(SDNode *N);
00213 
00214   /// SelectVLD - Select NEON load intrinsics.  NumVecs should be
00215   /// 1, 2, 3 or 4.  The opcode arrays specify the instructions used for
00216   /// loads of D registers and even subregs and odd subregs of Q registers.
00217   /// For NumVecs <= 2, QOpcodes1 is not used.
00218   SDNode *SelectVLD(SDNode *N, bool isUpdating, unsigned NumVecs,
00219                     const uint16_t *DOpcodes,
00220                     const uint16_t *QOpcodes0, const uint16_t *QOpcodes1);
00221 
00222   /// SelectVST - Select NEON store intrinsics.  NumVecs should
00223   /// be 1, 2, 3 or 4.  The opcode arrays specify the instructions used for
00224   /// stores of D registers and even subregs and odd subregs of Q registers.
00225   /// For NumVecs <= 2, QOpcodes1 is not used.
00226   SDNode *SelectVST(SDNode *N, bool isUpdating, unsigned NumVecs,
00227                     const uint16_t *DOpcodes,
00228                     const uint16_t *QOpcodes0, const uint16_t *QOpcodes1);
00229 
00230   /// SelectVLDSTLane - Select NEON load/store lane intrinsics.  NumVecs should
00231   /// be 2, 3 or 4.  The opcode arrays specify the instructions used for
00232   /// load/store of D registers and Q registers.
00233   SDNode *SelectVLDSTLane(SDNode *N, bool IsLoad,
00234                           bool isUpdating, unsigned NumVecs,
00235                           const uint16_t *DOpcodes, const uint16_t *QOpcodes);
00236 
00237   /// SelectVLDDup - Select NEON load-duplicate intrinsics.  NumVecs
00238   /// should be 2, 3 or 4.  The opcode array specifies the instructions used
00239   /// for loading D registers.  (Q registers are not supported.)
00240   SDNode *SelectVLDDup(SDNode *N, bool isUpdating, unsigned NumVecs,
00241                        const uint16_t *Opcodes);
00242 
00243   /// SelectVTBL - Select NEON VTBL and VTBX intrinsics.  NumVecs should be 2,
00244   /// 3 or 4.  These are custom-selected so that a REG_SEQUENCE can be
00245   /// generated to force the table registers to be consecutive.
00246   SDNode *SelectVTBL(SDNode *N, bool IsExt, unsigned NumVecs, unsigned Opc);
00247 
00248   /// SelectV6T2BitfieldExtractOp - Select SBFX/UBFX instructions for ARM.
00249   SDNode *SelectV6T2BitfieldExtractOp(SDNode *N, bool isSigned);
00250 
00251   // Select special operations if node forms integer ABS pattern
00252   SDNode *SelectABSOp(SDNode *N);
00253 
00254   SDNode *SelectInlineAsm(SDNode *N);
00255 
00256   SDNode *SelectConcatVector(SDNode *N);
00257 
00258   /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
00259   /// inline asm expressions.
00260   bool SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
00261                                     std::vector<SDValue> &OutOps) override;
00262 
00263   // Form pairs of consecutive R, S, D, or Q registers.
00264   SDNode *createGPRPairNode(EVT VT, SDValue V0, SDValue V1);
00265   SDNode *createSRegPairNode(EVT VT, SDValue V0, SDValue V1);
00266   SDNode *createDRegPairNode(EVT VT, SDValue V0, SDValue V1);
00267   SDNode *createQRegPairNode(EVT VT, SDValue V0, SDValue V1);
00268 
00269   // Form sequences of 4 consecutive S, D, or Q registers.
00270   SDNode *createQuadSRegsNode(EVT VT, SDValue V0, SDValue V1, SDValue V2, SDValue V3);
00271   SDNode *createQuadDRegsNode(EVT VT, SDValue V0, SDValue V1, SDValue V2, SDValue V3);
00272   SDNode *createQuadQRegsNode(EVT VT, SDValue V0, SDValue V1, SDValue V2, SDValue V3);
00273 
00274   // Get the alignment operand for a NEON VLD or VST instruction.
00275   SDValue GetVLDSTAlign(SDValue Align, unsigned NumVecs, bool is64BitVector);
00276 };
00277 }
00278 
00279 /// isInt32Immediate - This method tests to see if the node is a 32-bit constant
00280 /// operand. If so Imm will receive the 32-bit value.
00281 static bool isInt32Immediate(SDNode *N, unsigned &Imm) {
00282   if (N->getOpcode() == ISD::Constant && N->getValueType(0) == MVT::i32) {
00283     Imm = cast<ConstantSDNode>(N)->getZExtValue();
00284     return true;
00285   }
00286   return false;
00287 }
00288 
00289 // isInt32Immediate - This method tests to see if a constant operand.
00290 // If so Imm will receive the 32 bit value.
00291 static bool isInt32Immediate(SDValue N, unsigned &Imm) {
00292   return isInt32Immediate(N.getNode(), Imm);
00293 }
00294 
00295 // isOpcWithIntImmediate - This method tests to see if the node is a specific
00296 // opcode and that it has a immediate integer right operand.
00297 // If so Imm will receive the 32 bit value.
00298 static bool isOpcWithIntImmediate(SDNode *N, unsigned Opc, unsigned& Imm) {
00299   return N->getOpcode() == Opc &&
00300          isInt32Immediate(N->getOperand(1).getNode(), Imm);
00301 }
00302 
00303 /// \brief Check whether a particular node is a constant value representable as
00304 /// (N * Scale) where (N in [\p RangeMin, \p RangeMax).
00305 ///
00306 /// \param ScaledConstant [out] - On success, the pre-scaled constant value.
00307 static bool isScaledConstantInRange(SDValue Node, int Scale,
00308                                     int RangeMin, int RangeMax,
00309                                     int &ScaledConstant) {
00310   assert(Scale > 0 && "Invalid scale!");
00311 
00312   // Check that this is a constant.
00313   const ConstantSDNode *C = dyn_cast<ConstantSDNode>(Node);
00314   if (!C)
00315     return false;
00316 
00317   ScaledConstant = (int) C->getZExtValue();
00318   if ((ScaledConstant % Scale) != 0)
00319     return false;
00320 
00321   ScaledConstant /= Scale;
00322   return ScaledConstant >= RangeMin && ScaledConstant < RangeMax;
00323 }
00324 
00325 void ARMDAGToDAGISel::PreprocessISelDAG() {
00326   if (!Subtarget->hasV6T2Ops())
00327     return;
00328 
00329   bool isThumb2 = Subtarget->isThumb();
00330   for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(),
00331        E = CurDAG->allnodes_end(); I != E; ) {
00332     SDNode *N = I++;  // Preincrement iterator to avoid invalidation issues.
00333 
00334     if (N->getOpcode() != ISD::ADD)
00335       continue;
00336 
00337     // Look for (add X1, (and (srl X2, c1), c2)) where c2 is constant with
00338     // leading zeros, followed by consecutive set bits, followed by 1 or 2
00339     // trailing zeros, e.g. 1020.
00340     // Transform the expression to
00341     // (add X1, (shl (and (srl X2, c1), (c2>>tz)), tz)) where tz is the number
00342     // of trailing zeros of c2. The left shift would be folded as an shifter
00343     // operand of 'add' and the 'and' and 'srl' would become a bits extraction
00344     // node (UBFX).
00345 
00346     SDValue N0 = N->getOperand(0);
00347     SDValue N1 = N->getOperand(1);
00348     unsigned And_imm = 0;
00349     if (!isOpcWithIntImmediate(N1.getNode(), ISD::AND, And_imm)) {
00350       if (isOpcWithIntImmediate(N0.getNode(), ISD::AND, And_imm))
00351         std::swap(N0, N1);
00352     }
00353     if (!And_imm)
00354       continue;
00355 
00356     // Check if the AND mask is an immediate of the form: 000.....1111111100
00357     unsigned TZ = countTrailingZeros(And_imm);
00358     if (TZ != 1 && TZ != 2)
00359       // Be conservative here. Shifter operands aren't always free. e.g. On
00360       // Swift, left shifter operand of 1 / 2 for free but others are not.
00361       // e.g.
00362       //  ubfx   r3, r1, #16, #8
00363       //  ldr.w  r3, [r0, r3, lsl #2]
00364       // vs.
00365       //  mov.w  r9, #1020
00366       //  and.w  r2, r9, r1, lsr #14
00367       //  ldr    r2, [r0, r2]
00368       continue;
00369     And_imm >>= TZ;
00370     if (And_imm & (And_imm + 1))
00371       continue;
00372 
00373     // Look for (and (srl X, c1), c2).
00374     SDValue Srl = N1.getOperand(0);
00375     unsigned Srl_imm = 0;
00376     if (!isOpcWithIntImmediate(Srl.getNode(), ISD::SRL, Srl_imm) ||
00377         (Srl_imm <= 2))
00378       continue;
00379 
00380     // Make sure first operand is not a shifter operand which would prevent
00381     // folding of the left shift.
00382     SDValue CPTmp0;
00383     SDValue CPTmp1;
00384     SDValue CPTmp2;
00385     if (isThumb2) {
00386       if (SelectT2ShifterOperandReg(N0, CPTmp0, CPTmp1))
00387         continue;
00388     } else {
00389       if (SelectImmShifterOperand(N0, CPTmp0, CPTmp1) ||
00390           SelectRegShifterOperand(N0, CPTmp0, CPTmp1, CPTmp2))
00391         continue;
00392     }
00393 
00394     // Now make the transformation.
00395     Srl = CurDAG->getNode(ISD::SRL, SDLoc(Srl), MVT::i32,
00396                           Srl.getOperand(0),
00397                           CurDAG->getConstant(Srl_imm+TZ, MVT::i32));
00398     N1 = CurDAG->getNode(ISD::AND, SDLoc(N1), MVT::i32,
00399                          Srl, CurDAG->getConstant(And_imm, MVT::i32));
00400     N1 = CurDAG->getNode(ISD::SHL, SDLoc(N1), MVT::i32,
00401                          N1, CurDAG->getConstant(TZ, MVT::i32));
00402     CurDAG->UpdateNodeOperands(N, N0, N1);
00403   }
00404 }
00405 
00406 /// hasNoVMLxHazardUse - Return true if it's desirable to select a FP MLA / MLS
00407 /// node. VFP / NEON fp VMLA / VMLS instructions have special RAW hazards (at
00408 /// least on current ARM implementations) which should be avoidded.
00409 bool ARMDAGToDAGISel::hasNoVMLxHazardUse(SDNode *N) const {
00410   if (OptLevel == CodeGenOpt::None)
00411     return true;
00412 
00413   if (!CheckVMLxHazard)
00414     return true;
00415 
00416   if (!Subtarget->isCortexA7() && !Subtarget->isCortexA8() &&
00417       !Subtarget->isCortexA9() && !Subtarget->isSwift())
00418     return true;
00419 
00420   if (!N->hasOneUse())
00421     return false;
00422 
00423   SDNode *Use = *N->use_begin();
00424   if (Use->getOpcode() == ISD::CopyToReg)
00425     return true;
00426   if (Use->isMachineOpcode()) {
00427     const ARMBaseInstrInfo *TII = static_cast<const ARMBaseInstrInfo *>(
00428         CurDAG->getSubtarget().getInstrInfo());
00429 
00430     const MCInstrDesc &MCID = TII->get(Use->getMachineOpcode());
00431     if (MCID.mayStore())
00432       return true;
00433     unsigned Opcode = MCID.getOpcode();
00434     if (Opcode == ARM::VMOVRS || Opcode == ARM::VMOVRRD)
00435       return true;
00436     // vmlx feeding into another vmlx. We actually want to unfold
00437     // the use later in the MLxExpansion pass. e.g.
00438     // vmla
00439     // vmla (stall 8 cycles)
00440     //
00441     // vmul (5 cycles)
00442     // vadd (5 cycles)
00443     // vmla
00444     // This adds up to about 18 - 19 cycles.
00445     //
00446     // vmla
00447     // vmul (stall 4 cycles)
00448     // vadd adds up to about 14 cycles.
00449     return TII->isFpMLxInstruction(Opcode);
00450   }
00451 
00452   return false;
00453 }
00454 
00455 bool ARMDAGToDAGISel::isShifterOpProfitable(const SDValue &Shift,
00456                                             ARM_AM::ShiftOpc ShOpcVal,
00457                                             unsigned ShAmt) {
00458   if (!Subtarget->isLikeA9() && !Subtarget->isSwift())
00459     return true;
00460   if (Shift.hasOneUse())
00461     return true;
00462   // R << 2 is free.
00463   return ShOpcVal == ARM_AM::lsl &&
00464          (ShAmt == 2 || (Subtarget->isSwift() && ShAmt == 1));
00465 }
00466 
00467 bool ARMDAGToDAGISel::SelectImmShifterOperand(SDValue N,
00468                                               SDValue &BaseReg,
00469                                               SDValue &Opc,
00470                                               bool CheckProfitability) {
00471   if (DisableShifterOp)
00472     return false;
00473 
00474   ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOpcode());
00475 
00476   // Don't match base register only case. That is matched to a separate
00477   // lower complexity pattern with explicit register operand.
00478   if (ShOpcVal == ARM_AM::no_shift) return false;
00479 
00480   BaseReg = N.getOperand(0);
00481   unsigned ShImmVal = 0;
00482   ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1));
00483   if (!RHS) return false;
00484   ShImmVal = RHS->getZExtValue() & 31;
00485   Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal),
00486                                   MVT::i32);
00487   return true;
00488 }
00489 
00490 bool ARMDAGToDAGISel::SelectRegShifterOperand(SDValue N,
00491                                               SDValue &BaseReg,
00492                                               SDValue &ShReg,
00493                                               SDValue &Opc,
00494                                               bool CheckProfitability) {
00495   if (DisableShifterOp)
00496     return false;
00497 
00498   ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOpcode());
00499 
00500   // Don't match base register only case. That is matched to a separate
00501   // lower complexity pattern with explicit register operand.
00502   if (ShOpcVal == ARM_AM::no_shift) return false;
00503 
00504   BaseReg = N.getOperand(0);
00505   unsigned ShImmVal = 0;
00506   ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1));
00507   if (RHS) return false;
00508 
00509   ShReg = N.getOperand(1);
00510   if (CheckProfitability && !isShifterOpProfitable(N, ShOpcVal, ShImmVal))
00511     return false;
00512   Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal),
00513                                   MVT::i32);
00514   return true;
00515 }
00516 
00517 
00518 bool ARMDAGToDAGISel::SelectAddrModeImm12(SDValue N,
00519                                           SDValue &Base,
00520                                           SDValue &OffImm) {
00521   // Match simple R + imm12 operands.
00522 
00523   // Base only.
00524   if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB &&
00525       !CurDAG->isBaseWithConstantOffset(N)) {
00526     if (N.getOpcode() == ISD::FrameIndex) {
00527       // Match frame index.
00528       int FI = cast<FrameIndexSDNode>(N)->getIndex();
00529       Base = CurDAG->getTargetFrameIndex(FI,
00530                                          getTargetLowering()->getPointerTy());
00531       OffImm  = CurDAG->getTargetConstant(0, MVT::i32);
00532       return true;
00533     }
00534 
00535     if (N.getOpcode() == ARMISD::Wrapper &&
00536         N.getOperand(0).getOpcode() != ISD::TargetGlobalAddress) {
00537       Base = N.getOperand(0);
00538     } else
00539       Base = N;
00540     OffImm  = CurDAG->getTargetConstant(0, MVT::i32);
00541     return true;
00542   }
00543 
00544   if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
00545     int RHSC = (int)RHS->getSExtValue();
00546     if (N.getOpcode() == ISD::SUB)
00547       RHSC = -RHSC;
00548 
00549     if (RHSC > -0x1000 && RHSC < 0x1000) { // 12 bits
00550       Base   = N.getOperand(0);
00551       if (Base.getOpcode() == ISD::FrameIndex) {
00552         int FI = cast<FrameIndexSDNode>(Base)->getIndex();
00553         Base = CurDAG->getTargetFrameIndex(FI,
00554                                            getTargetLowering()->getPointerTy());
00555       }
00556       OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32);
00557       return true;
00558     }
00559   }
00560 
00561   // Base only.
00562   Base = N;
00563   OffImm  = CurDAG->getTargetConstant(0, MVT::i32);
00564   return true;
00565 }
00566 
00567 
00568 
00569 bool ARMDAGToDAGISel::SelectLdStSOReg(SDValue N, SDValue &Base, SDValue &Offset,
00570                                       SDValue &Opc) {
00571   if (N.getOpcode() == ISD::MUL &&
00572       ((!Subtarget->isLikeA9() && !Subtarget->isSwift()) || N.hasOneUse())) {
00573     if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
00574       // X * [3,5,9] -> X + X * [2,4,8] etc.
00575       int RHSC = (int)RHS->getZExtValue();
00576       if (RHSC & 1) {
00577         RHSC = RHSC & ~1;
00578         ARM_AM::AddrOpc AddSub = ARM_AM::add;
00579         if (RHSC < 0) {
00580           AddSub = ARM_AM::sub;
00581           RHSC = - RHSC;
00582         }
00583         if (isPowerOf2_32(RHSC)) {
00584           unsigned ShAmt = Log2_32(RHSC);
00585           Base = Offset = N.getOperand(0);
00586           Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt,
00587                                                             ARM_AM::lsl),
00588                                           MVT::i32);
00589           return true;
00590         }
00591       }
00592     }
00593   }
00594 
00595   if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB &&
00596       // ISD::OR that is equivalent to an ISD::ADD.
00597       !CurDAG->isBaseWithConstantOffset(N))
00598     return false;
00599 
00600   // Leave simple R +/- imm12 operands for LDRi12
00601   if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::OR) {
00602     int RHSC;
00603     if (isScaledConstantInRange(N.getOperand(1), /*Scale=*/1,
00604                                 -0x1000+1, 0x1000, RHSC)) // 12 bits.
00605       return false;
00606   }
00607 
00608   // Otherwise this is R +/- [possibly shifted] R.
00609   ARM_AM::AddrOpc AddSub = N.getOpcode() == ISD::SUB ? ARM_AM::sub:ARM_AM::add;
00610   ARM_AM::ShiftOpc ShOpcVal =
00611     ARM_AM::getShiftOpcForNode(N.getOperand(1).getOpcode());
00612   unsigned ShAmt = 0;
00613 
00614   Base   = N.getOperand(0);
00615   Offset = N.getOperand(1);
00616 
00617   if (ShOpcVal != ARM_AM::no_shift) {
00618     // Check to see if the RHS of the shift is a constant, if not, we can't fold
00619     // it.
00620     if (ConstantSDNode *Sh =
00621            dyn_cast<ConstantSDNode>(N.getOperand(1).getOperand(1))) {
00622       ShAmt = Sh->getZExtValue();
00623       if (isShifterOpProfitable(Offset, ShOpcVal, ShAmt))
00624         Offset = N.getOperand(1).getOperand(0);
00625       else {
00626         ShAmt = 0;
00627         ShOpcVal = ARM_AM::no_shift;
00628       }
00629     } else {
00630       ShOpcVal = ARM_AM::no_shift;
00631     }
00632   }
00633 
00634   // Try matching (R shl C) + (R).
00635   if (N.getOpcode() != ISD::SUB && ShOpcVal == ARM_AM::no_shift &&
00636       !(Subtarget->isLikeA9() || Subtarget->isSwift() ||
00637         N.getOperand(0).hasOneUse())) {
00638     ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(0).getOpcode());
00639     if (ShOpcVal != ARM_AM::no_shift) {
00640       // Check to see if the RHS of the shift is a constant, if not, we can't
00641       // fold it.
00642       if (ConstantSDNode *Sh =
00643           dyn_cast<ConstantSDNode>(N.getOperand(0).getOperand(1))) {
00644         ShAmt = Sh->getZExtValue();
00645         if (isShifterOpProfitable(N.getOperand(0), ShOpcVal, ShAmt)) {
00646           Offset = N.getOperand(0).getOperand(0);
00647           Base = N.getOperand(1);
00648         } else {
00649           ShAmt = 0;
00650           ShOpcVal = ARM_AM::no_shift;
00651         }
00652       } else {
00653         ShOpcVal = ARM_AM::no_shift;
00654       }
00655     }
00656   }
00657 
00658   Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal),
00659                                   MVT::i32);
00660   return true;
00661 }
00662 
00663 
00664 //-----
00665 
00666 AddrMode2Type ARMDAGToDAGISel::SelectAddrMode2Worker(SDValue N,
00667                                                      SDValue &Base,
00668                                                      SDValue &Offset,
00669                                                      SDValue &Opc) {
00670   if (N.getOpcode() == ISD::MUL &&
00671       (!(Subtarget->isLikeA9() || Subtarget->isSwift()) || N.hasOneUse())) {
00672     if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
00673       // X * [3,5,9] -> X + X * [2,4,8] etc.
00674       int RHSC = (int)RHS->getZExtValue();
00675       if (RHSC & 1) {
00676         RHSC = RHSC & ~1;
00677         ARM_AM::AddrOpc AddSub = ARM_AM::add;
00678         if (RHSC < 0) {
00679           AddSub = ARM_AM::sub;
00680           RHSC = - RHSC;
00681         }
00682         if (isPowerOf2_32(RHSC)) {
00683           unsigned ShAmt = Log2_32(RHSC);
00684           Base = Offset = N.getOperand(0);
00685           Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt,
00686                                                             ARM_AM::lsl),
00687                                           MVT::i32);
00688           return AM2_SHOP;
00689         }
00690       }
00691     }
00692   }
00693 
00694   if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB &&
00695       // ISD::OR that is equivalent to an ADD.
00696       !CurDAG->isBaseWithConstantOffset(N)) {
00697     Base = N;
00698     if (N.getOpcode() == ISD::FrameIndex) {
00699       int FI = cast<FrameIndexSDNode>(N)->getIndex();
00700       Base = CurDAG->getTargetFrameIndex(FI,
00701                                          getTargetLowering()->getPointerTy());
00702     } else if (N.getOpcode() == ARMISD::Wrapper &&
00703                N.getOperand(0).getOpcode() != ISD::TargetGlobalAddress) {
00704       Base = N.getOperand(0);
00705     }
00706     Offset = CurDAG->getRegister(0, MVT::i32);
00707     Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0,
00708                                                       ARM_AM::no_shift),
00709                                     MVT::i32);
00710     return AM2_BASE;
00711   }
00712 
00713   // Match simple R +/- imm12 operands.
00714   if (N.getOpcode() != ISD::SUB) {
00715     int RHSC;
00716     if (isScaledConstantInRange(N.getOperand(1), /*Scale=*/1,
00717                                 -0x1000+1, 0x1000, RHSC)) { // 12 bits.
00718       Base = N.getOperand(0);
00719       if (Base.getOpcode() == ISD::FrameIndex) {
00720         int FI = cast<FrameIndexSDNode>(Base)->getIndex();
00721         Base = CurDAG->getTargetFrameIndex(FI,
00722                                            getTargetLowering()->getPointerTy());
00723       }
00724       Offset = CurDAG->getRegister(0, MVT::i32);
00725 
00726       ARM_AM::AddrOpc AddSub = ARM_AM::add;
00727       if (RHSC < 0) {
00728         AddSub = ARM_AM::sub;
00729         RHSC = - RHSC;
00730       }
00731       Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, RHSC,
00732                                                         ARM_AM::no_shift),
00733                                       MVT::i32);
00734       return AM2_BASE;
00735     }
00736   }
00737 
00738   if ((Subtarget->isLikeA9() || Subtarget->isSwift()) && !N.hasOneUse()) {
00739     // Compute R +/- (R << N) and reuse it.
00740     Base = N;
00741     Offset = CurDAG->getRegister(0, MVT::i32);
00742     Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0,
00743                                                       ARM_AM::no_shift),
00744                                     MVT::i32);
00745     return AM2_BASE;
00746   }
00747 
00748   // Otherwise this is R +/- [possibly shifted] R.
00749   ARM_AM::AddrOpc AddSub = N.getOpcode() != ISD::SUB ? ARM_AM::add:ARM_AM::sub;
00750   ARM_AM::ShiftOpc ShOpcVal =
00751     ARM_AM::getShiftOpcForNode(N.getOperand(1).getOpcode());
00752   unsigned ShAmt = 0;
00753 
00754   Base   = N.getOperand(0);
00755   Offset = N.getOperand(1);
00756 
00757   if (ShOpcVal != ARM_AM::no_shift) {
00758     // Check to see if the RHS of the shift is a constant, if not, we can't fold
00759     // it.
00760     if (ConstantSDNode *Sh =
00761            dyn_cast<ConstantSDNode>(N.getOperand(1).getOperand(1))) {
00762       ShAmt = Sh->getZExtValue();
00763       if (isShifterOpProfitable(Offset, ShOpcVal, ShAmt))
00764         Offset = N.getOperand(1).getOperand(0);
00765       else {
00766         ShAmt = 0;
00767         ShOpcVal = ARM_AM::no_shift;
00768       }
00769     } else {
00770       ShOpcVal = ARM_AM::no_shift;
00771     }
00772   }
00773 
00774   // Try matching (R shl C) + (R).
00775   if (N.getOpcode() != ISD::SUB && ShOpcVal == ARM_AM::no_shift &&
00776       !(Subtarget->isLikeA9() || Subtarget->isSwift() ||
00777         N.getOperand(0).hasOneUse())) {
00778     ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(0).getOpcode());
00779     if (ShOpcVal != ARM_AM::no_shift) {
00780       // Check to see if the RHS of the shift is a constant, if not, we can't
00781       // fold it.
00782       if (ConstantSDNode *Sh =
00783           dyn_cast<ConstantSDNode>(N.getOperand(0).getOperand(1))) {
00784         ShAmt = Sh->getZExtValue();
00785         if (isShifterOpProfitable(N.getOperand(0), ShOpcVal, ShAmt)) {
00786           Offset = N.getOperand(0).getOperand(0);
00787           Base = N.getOperand(1);
00788         } else {
00789           ShAmt = 0;
00790           ShOpcVal = ARM_AM::no_shift;
00791         }
00792       } else {
00793         ShOpcVal = ARM_AM::no_shift;
00794       }
00795     }
00796   }
00797 
00798   Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal),
00799                                   MVT::i32);
00800   return AM2_SHOP;
00801 }
00802 
00803 bool ARMDAGToDAGISel::SelectAddrMode2OffsetReg(SDNode *Op, SDValue N,
00804                                             SDValue &Offset, SDValue &Opc) {
00805   unsigned Opcode = Op->getOpcode();
00806   ISD::MemIndexedMode AM = (Opcode == ISD::LOAD)
00807     ? cast<LoadSDNode>(Op)->getAddressingMode()
00808     : cast<StoreSDNode>(Op)->getAddressingMode();
00809   ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC)
00810     ? ARM_AM::add : ARM_AM::sub;
00811   int Val;
00812   if (isScaledConstantInRange(N, /*Scale=*/1, 0, 0x1000, Val))
00813     return false;
00814 
00815   Offset = N;
00816   ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOpcode());
00817   unsigned ShAmt = 0;
00818   if (ShOpcVal != ARM_AM::no_shift) {
00819     // Check to see if the RHS of the shift is a constant, if not, we can't fold
00820     // it.
00821     if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
00822       ShAmt = Sh->getZExtValue();
00823       if (isShifterOpProfitable(N, ShOpcVal, ShAmt))
00824         Offset = N.getOperand(0);
00825       else {
00826         ShAmt = 0;
00827         ShOpcVal = ARM_AM::no_shift;
00828       }
00829     } else {
00830       ShOpcVal = ARM_AM::no_shift;
00831     }
00832   }
00833 
00834   Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal),
00835                                   MVT::i32);
00836   return true;
00837 }
00838 
00839 bool ARMDAGToDAGISel::SelectAddrMode2OffsetImmPre(SDNode *Op, SDValue N,
00840                                             SDValue &Offset, SDValue &Opc) {
00841   unsigned Opcode = Op->getOpcode();
00842   ISD::MemIndexedMode AM = (Opcode == ISD::LOAD)
00843     ? cast<LoadSDNode>(Op)->getAddressingMode()
00844     : cast<StoreSDNode>(Op)->getAddressingMode();
00845   ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC)
00846     ? ARM_AM::add : ARM_AM::sub;
00847   int Val;
00848   if (isScaledConstantInRange(N, /*Scale=*/1, 0, 0x1000, Val)) { // 12 bits.
00849     if (AddSub == ARM_AM::sub) Val *= -1;
00850     Offset = CurDAG->getRegister(0, MVT::i32);
00851     Opc = CurDAG->getTargetConstant(Val, MVT::i32);
00852     return true;
00853   }
00854 
00855   return false;
00856 }
00857 
00858 
00859 bool ARMDAGToDAGISel::SelectAddrMode2OffsetImm(SDNode *Op, SDValue N,
00860                                             SDValue &Offset, SDValue &Opc) {
00861   unsigned Opcode = Op->getOpcode();
00862   ISD::MemIndexedMode AM = (Opcode == ISD::LOAD)
00863     ? cast<LoadSDNode>(Op)->getAddressingMode()
00864     : cast<StoreSDNode>(Op)->getAddressingMode();
00865   ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC)
00866     ? ARM_AM::add : ARM_AM::sub;
00867   int Val;
00868   if (isScaledConstantInRange(N, /*Scale=*/1, 0, 0x1000, Val)) { // 12 bits.
00869     Offset = CurDAG->getRegister(0, MVT::i32);
00870     Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, Val,
00871                                                       ARM_AM::no_shift),
00872                                     MVT::i32);
00873     return true;
00874   }
00875 
00876   return false;
00877 }
00878 
00879 bool ARMDAGToDAGISel::SelectAddrOffsetNone(SDValue N, SDValue &Base) {
00880   Base = N;
00881   return true;
00882 }
00883 
00884 bool ARMDAGToDAGISel::SelectAddrMode3(SDValue N,
00885                                       SDValue &Base, SDValue &Offset,
00886                                       SDValue &Opc) {
00887   if (N.getOpcode() == ISD::SUB) {
00888     // X - C  is canonicalize to X + -C, no need to handle it here.
00889     Base = N.getOperand(0);
00890     Offset = N.getOperand(1);
00891     Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::sub, 0),MVT::i32);
00892     return true;
00893   }
00894 
00895   if (!CurDAG->isBaseWithConstantOffset(N)) {
00896     Base = N;
00897     if (N.getOpcode() == ISD::FrameIndex) {
00898       int FI = cast<FrameIndexSDNode>(N)->getIndex();
00899       Base = CurDAG->getTargetFrameIndex(FI,
00900                                          getTargetLowering()->getPointerTy());
00901     }
00902     Offset = CurDAG->getRegister(0, MVT::i32);
00903     Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0),MVT::i32);
00904     return true;
00905   }
00906 
00907   // If the RHS is +/- imm8, fold into addr mode.
00908   int RHSC;
00909   if (isScaledConstantInRange(N.getOperand(1), /*Scale=*/1,
00910                               -256 + 1, 256, RHSC)) { // 8 bits.
00911     Base = N.getOperand(0);
00912     if (Base.getOpcode() == ISD::FrameIndex) {
00913       int FI = cast<FrameIndexSDNode>(Base)->getIndex();
00914       Base = CurDAG->getTargetFrameIndex(FI,
00915                                          getTargetLowering()->getPointerTy());
00916     }
00917     Offset = CurDAG->getRegister(0, MVT::i32);
00918 
00919     ARM_AM::AddrOpc AddSub = ARM_AM::add;
00920     if (RHSC < 0) {
00921       AddSub = ARM_AM::sub;
00922       RHSC = -RHSC;
00923     }
00924     Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, RHSC),MVT::i32);
00925     return true;
00926   }
00927 
00928   Base = N.getOperand(0);
00929   Offset = N.getOperand(1);
00930   Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0), MVT::i32);
00931   return true;
00932 }
00933 
00934 bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDNode *Op, SDValue N,
00935                                             SDValue &Offset, SDValue &Opc) {
00936   unsigned Opcode = Op->getOpcode();
00937   ISD::MemIndexedMode AM = (Opcode == ISD::LOAD)
00938     ? cast<LoadSDNode>(Op)->getAddressingMode()
00939     : cast<StoreSDNode>(Op)->getAddressingMode();
00940   ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC)
00941     ? ARM_AM::add : ARM_AM::sub;
00942   int Val;
00943   if (isScaledConstantInRange(N, /*Scale=*/1, 0, 256, Val)) { // 12 bits.
00944     Offset = CurDAG->getRegister(0, MVT::i32);
00945     Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, Val), MVT::i32);
00946     return true;
00947   }
00948 
00949   Offset = N;
00950   Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, 0), MVT::i32);
00951   return true;
00952 }
00953 
00954 bool ARMDAGToDAGISel::SelectAddrMode5(SDValue N,
00955                                       SDValue &Base, SDValue &Offset) {
00956   if (!CurDAG->isBaseWithConstantOffset(N)) {
00957     Base = N;
00958     if (N.getOpcode() == ISD::FrameIndex) {
00959       int FI = cast<FrameIndexSDNode>(N)->getIndex();
00960       Base = CurDAG->getTargetFrameIndex(FI,
00961                                          getTargetLowering()->getPointerTy());
00962     } else if (N.getOpcode() == ARMISD::Wrapper &&
00963                N.getOperand(0).getOpcode() != ISD::TargetGlobalAddress) {
00964       Base = N.getOperand(0);
00965     }
00966     Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0),
00967                                        MVT::i32);
00968     return true;
00969   }
00970 
00971   // If the RHS is +/- imm8, fold into addr mode.
00972   int RHSC;
00973   if (isScaledConstantInRange(N.getOperand(1), /*Scale=*/4,
00974                               -256 + 1, 256, RHSC)) {
00975     Base = N.getOperand(0);
00976     if (Base.getOpcode() == ISD::FrameIndex) {
00977       int FI = cast<FrameIndexSDNode>(Base)->getIndex();
00978       Base = CurDAG->getTargetFrameIndex(FI,
00979                                          getTargetLowering()->getPointerTy());
00980     }
00981 
00982     ARM_AM::AddrOpc AddSub = ARM_AM::add;
00983     if (RHSC < 0) {
00984       AddSub = ARM_AM::sub;
00985       RHSC = -RHSC;
00986     }
00987     Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(AddSub, RHSC),
00988                                        MVT::i32);
00989     return true;
00990   }
00991 
00992   Base = N;
00993   Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0),
00994                                      MVT::i32);
00995   return true;
00996 }
00997 
00998 bool ARMDAGToDAGISel::SelectAddrMode6(SDNode *Parent, SDValue N, SDValue &Addr,
00999                                       SDValue &Align) {
01000   Addr = N;
01001 
01002   unsigned Alignment = 0;
01003   if (LSBaseSDNode *LSN = dyn_cast<LSBaseSDNode>(Parent)) {
01004     // This case occurs only for VLD1-lane/dup and VST1-lane instructions.
01005     // The maximum alignment is equal to the memory size being referenced.
01006     unsigned LSNAlign = LSN->getAlignment();
01007     unsigned MemSize = LSN->getMemoryVT().getSizeInBits() / 8;
01008     if (LSNAlign >= MemSize && MemSize > 1)
01009       Alignment = MemSize;
01010   } else {
01011     // All other uses of addrmode6 are for intrinsics.  For now just record
01012     // the raw alignment value; it will be refined later based on the legal
01013     // alignment operands for the intrinsic.
01014     Alignment = cast<MemIntrinsicSDNode>(Parent)->getAlignment();
01015   }
01016 
01017   Align = CurDAG->getTargetConstant(Alignment, MVT::i32);
01018   return true;
01019 }
01020 
01021 bool ARMDAGToDAGISel::SelectAddrMode6Offset(SDNode *Op, SDValue N,
01022                                             SDValue &Offset) {
01023   LSBaseSDNode *LdSt = cast<LSBaseSDNode>(Op);
01024   ISD::MemIndexedMode AM = LdSt->getAddressingMode();
01025   if (AM != ISD::POST_INC)
01026     return false;
01027   Offset = N;
01028   if (ConstantSDNode *NC = dyn_cast<ConstantSDNode>(N)) {
01029     if (NC->getZExtValue() * 8 == LdSt->getMemoryVT().getSizeInBits())
01030       Offset = CurDAG->getRegister(0, MVT::i32);
01031   }
01032   return true;
01033 }
01034 
01035 bool ARMDAGToDAGISel::SelectAddrModePC(SDValue N,
01036                                        SDValue &Offset, SDValue &Label) {
01037   if (N.getOpcode() == ARMISD::PIC_ADD && N.hasOneUse()) {
01038     Offset = N.getOperand(0);
01039     SDValue N1 = N.getOperand(1);
01040     Label = CurDAG->getTargetConstant(cast<ConstantSDNode>(N1)->getZExtValue(),
01041                                       MVT::i32);
01042     return true;
01043   }
01044 
01045   return false;
01046 }
01047 
01048 
01049 //===----------------------------------------------------------------------===//
01050 //                         Thumb Addressing Modes
01051 //===----------------------------------------------------------------------===//
01052 
01053 bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDValue N,
01054                                             SDValue &Base, SDValue &Offset){
01055   if (N.getOpcode() != ISD::ADD && !CurDAG->isBaseWithConstantOffset(N)) {
01056     ConstantSDNode *NC = dyn_cast<ConstantSDNode>(N);
01057     if (!NC || !NC->isNullValue())
01058       return false;
01059 
01060     Base = Offset = N;
01061     return true;
01062   }
01063 
01064   Base = N.getOperand(0);
01065   Offset = N.getOperand(1);
01066   return true;
01067 }
01068 
01069 bool
01070 ARMDAGToDAGISel::SelectThumbAddrModeRI(SDValue N, SDValue &Base,
01071                                        SDValue &Offset, unsigned Scale) {
01072   if (Scale == 4) {
01073     SDValue TmpBase, TmpOffImm;
01074     if (SelectThumbAddrModeSP(N, TmpBase, TmpOffImm))
01075       return false;  // We want to select tLDRspi / tSTRspi instead.
01076 
01077     if (N.getOpcode() == ARMISD::Wrapper &&
01078         N.getOperand(0).getOpcode() == ISD::TargetConstantPool)
01079       return false;  // We want to select tLDRpci instead.
01080   }
01081 
01082   if (!CurDAG->isBaseWithConstantOffset(N))
01083     return false;
01084 
01085   // Thumb does not have [sp, r] address mode.
01086   RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(N.getOperand(0));
01087   RegisterSDNode *RHSR = dyn_cast<RegisterSDNode>(N.getOperand(1));
01088   if ((LHSR && LHSR->getReg() == ARM::SP) ||
01089       (RHSR && RHSR->getReg() == ARM::SP))
01090     return false;
01091 
01092   // FIXME: Why do we explicitly check for a match here and then return false?
01093   // Presumably to allow something else to match, but shouldn't this be
01094   // documented?
01095   int RHSC;
01096   if (isScaledConstantInRange(N.getOperand(1), Scale, 0, 32, RHSC))
01097     return false;
01098 
01099   Base = N.getOperand(0);
01100   Offset = N.getOperand(1);
01101   return true;
01102 }
01103 
01104 bool
01105 ARMDAGToDAGISel::SelectThumbAddrModeRI5S1(SDValue N,
01106                                           SDValue &Base,
01107                                           SDValue &Offset) {
01108   return SelectThumbAddrModeRI(N, Base, Offset, 1);
01109 }
01110 
01111 bool
01112 ARMDAGToDAGISel::SelectThumbAddrModeRI5S2(SDValue N,
01113                                           SDValue &Base,
01114                                           SDValue &Offset) {
01115   return SelectThumbAddrModeRI(N, Base, Offset, 2);
01116 }
01117 
01118 bool
01119 ARMDAGToDAGISel::SelectThumbAddrModeRI5S4(SDValue N,
01120                                           SDValue &Base,
01121                                           SDValue &Offset) {
01122   return SelectThumbAddrModeRI(N, Base, Offset, 4);
01123 }
01124 
01125 bool
01126 ARMDAGToDAGISel::SelectThumbAddrModeImm5S(SDValue N, unsigned Scale,
01127                                           SDValue &Base, SDValue &OffImm) {
01128   if (Scale == 4) {
01129     SDValue TmpBase, TmpOffImm;
01130     if (SelectThumbAddrModeSP(N, TmpBase, TmpOffImm))
01131       return false;  // We want to select tLDRspi / tSTRspi instead.
01132 
01133     if (N.getOpcode() == ARMISD::Wrapper &&
01134         N.getOperand(0).getOpcode() == ISD::TargetConstantPool)
01135       return false;  // We want to select tLDRpci instead.
01136   }
01137 
01138   if (!CurDAG->isBaseWithConstantOffset(N)) {
01139     if (N.getOpcode() == ARMISD::Wrapper &&
01140         N.getOperand(0).getOpcode() != ISD::TargetGlobalAddress) {
01141       Base = N.getOperand(0);
01142     } else {
01143       Base = N;
01144     }
01145 
01146     OffImm = CurDAG->getTargetConstant(0, MVT::i32);
01147     return true;
01148   }
01149 
01150   RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(N.getOperand(0));
01151   RegisterSDNode *RHSR = dyn_cast<RegisterSDNode>(N.getOperand(1));
01152   if ((LHSR && LHSR->getReg() == ARM::SP) ||
01153       (RHSR && RHSR->getReg() == ARM::SP)) {
01154     ConstantSDNode *LHS = dyn_cast<ConstantSDNode>(N.getOperand(0));
01155     ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1));
01156     unsigned LHSC = LHS ? LHS->getZExtValue() : 0;
01157     unsigned RHSC = RHS ? RHS->getZExtValue() : 0;
01158 
01159     // Thumb does not have [sp, #imm5] address mode for non-zero imm5.
01160     if (LHSC != 0 || RHSC != 0) return false;
01161 
01162     Base = N;
01163     OffImm = CurDAG->getTargetConstant(0, MVT::i32);
01164     return true;
01165   }
01166 
01167   // If the RHS is + imm5 * scale, fold into addr mode.
01168   int RHSC;
01169   if (isScaledConstantInRange(N.getOperand(1), Scale, 0, 32, RHSC)) {
01170     Base = N.getOperand(0);
01171     OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32);
01172     return true;
01173   }
01174 
01175   Base = N.getOperand(0);
01176   OffImm = CurDAG->getTargetConstant(0, MVT::i32);
01177   return true;
01178 }
01179 
01180 bool
01181 ARMDAGToDAGISel::SelectThumbAddrModeImm5S4(SDValue N, SDValue &Base,
01182                                            SDValue &OffImm) {
01183   return SelectThumbAddrModeImm5S(N, 4, Base, OffImm);
01184 }
01185 
01186 bool
01187 ARMDAGToDAGISel::SelectThumbAddrModeImm5S2(SDValue N, SDValue &Base,
01188                                            SDValue &OffImm) {
01189   return SelectThumbAddrModeImm5S(N, 2, Base, OffImm);
01190 }
01191 
01192 bool
01193 ARMDAGToDAGISel::SelectThumbAddrModeImm5S1(SDValue N, SDValue &Base,
01194                                            SDValue &OffImm) {
01195   return SelectThumbAddrModeImm5S(N, 1, Base, OffImm);
01196 }
01197 
01198 bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDValue N,
01199                                             SDValue &Base, SDValue &OffImm) {
01200   if (N.getOpcode() == ISD::FrameIndex) {
01201     int FI = cast<FrameIndexSDNode>(N)->getIndex();
01202     Base = CurDAG->getTargetFrameIndex(FI,
01203                                        getTargetLowering()->getPointerTy());
01204     OffImm = CurDAG->getTargetConstant(0, MVT::i32);
01205     return true;
01206   }
01207 
01208   if (!CurDAG->isBaseWithConstantOffset(N))
01209     return false;
01210 
01211   RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(N.getOperand(0));
01212   if (N.getOperand(0).getOpcode() == ISD::FrameIndex ||
01213       (LHSR && LHSR->getReg() == ARM::SP)) {
01214     // If the RHS is + imm8 * scale, fold into addr mode.
01215     int RHSC;
01216     if (isScaledConstantInRange(N.getOperand(1), /*Scale=*/4, 0, 256, RHSC)) {
01217       Base = N.getOperand(0);
01218       if (Base.getOpcode() == ISD::FrameIndex) {
01219         int FI = cast<FrameIndexSDNode>(Base)->getIndex();
01220         Base = CurDAG->getTargetFrameIndex(FI,
01221                                            getTargetLowering()->getPointerTy());
01222       }
01223       OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32);
01224       return true;
01225     }
01226   }
01227 
01228   return false;
01229 }
01230 
01231 
01232 //===----------------------------------------------------------------------===//
01233 //                        Thumb 2 Addressing Modes
01234 //===----------------------------------------------------------------------===//
01235 
01236 
01237 bool ARMDAGToDAGISel::SelectT2ShifterOperandReg(SDValue N, SDValue &BaseReg,
01238                                                 SDValue &Opc) {
01239   if (DisableShifterOp)
01240     return false;
01241 
01242   ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOpcode());
01243 
01244   // Don't match base register only case. That is matched to a separate
01245   // lower complexity pattern with explicit register operand.
01246   if (ShOpcVal == ARM_AM::no_shift) return false;
01247 
01248   BaseReg = N.getOperand(0);
01249   unsigned ShImmVal = 0;
01250   if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
01251     ShImmVal = RHS->getZExtValue() & 31;
01252     Opc = getI32Imm(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal));
01253     return true;
01254   }
01255 
01256   return false;
01257 }
01258 
01259 bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDValue N,
01260                                             SDValue &Base, SDValue &OffImm) {
01261   // Match simple R + imm12 operands.
01262 
01263   // Base only.
01264   if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB &&
01265       !CurDAG->isBaseWithConstantOffset(N)) {
01266     if (N.getOpcode() == ISD::FrameIndex) {
01267       // Match frame index.
01268       int FI = cast<FrameIndexSDNode>(N)->getIndex();
01269       Base = CurDAG->getTargetFrameIndex(FI,
01270                                          getTargetLowering()->getPointerTy());
01271       OffImm  = CurDAG->getTargetConstant(0, MVT::i32);
01272       return true;
01273     }
01274 
01275     if (N.getOpcode() == ARMISD::Wrapper &&
01276         N.getOperand(0).getOpcode() != ISD::TargetGlobalAddress) {
01277       Base = N.getOperand(0);
01278       if (Base.getOpcode() == ISD::TargetConstantPool)
01279         return false;  // We want to select t2LDRpci instead.
01280     } else
01281       Base = N;
01282     OffImm  = CurDAG->getTargetConstant(0, MVT::i32);
01283     return true;
01284   }
01285 
01286   if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
01287     if (SelectT2AddrModeImm8(N, Base, OffImm))
01288       // Let t2LDRi8 handle (R - imm8).
01289       return false;
01290 
01291     int RHSC = (int)RHS->getZExtValue();
01292     if (N.getOpcode() == ISD::SUB)
01293       RHSC = -RHSC;
01294 
01295     if (RHSC >= 0 && RHSC < 0x1000) { // 12 bits (unsigned)
01296       Base   = N.getOperand(0);
01297       if (Base.getOpcode() == ISD::FrameIndex) {
01298         int FI = cast<FrameIndexSDNode>(Base)->getIndex();
01299         Base = CurDAG->getTargetFrameIndex(FI,
01300                                            getTargetLowering()->getPointerTy());
01301       }
01302       OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32);
01303       return true;
01304     }
01305   }
01306 
01307   // Base only.
01308   Base = N;
01309   OffImm  = CurDAG->getTargetConstant(0, MVT::i32);
01310   return true;
01311 }
01312 
01313 bool ARMDAGToDAGISel::SelectT2AddrModeImm8(SDValue N,
01314                                            SDValue &Base, SDValue &OffImm) {
01315   // Match simple R - imm8 operands.
01316   if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB &&
01317       !CurDAG->isBaseWithConstantOffset(N))
01318     return false;
01319 
01320   if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
01321     int RHSC = (int)RHS->getSExtValue();
01322     if (N.getOpcode() == ISD::SUB)
01323       RHSC = -RHSC;
01324 
01325     if ((RHSC >= -255) && (RHSC < 0)) { // 8 bits (always negative)
01326       Base = N.getOperand(0);
01327       if (Base.getOpcode() == ISD::FrameIndex) {
01328         int FI = cast<FrameIndexSDNode>(Base)->getIndex();
01329         Base = CurDAG->getTargetFrameIndex(FI,
01330                                            getTargetLowering()->getPointerTy());
01331       }
01332       OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32);
01333       return true;
01334     }
01335   }
01336 
01337   return false;
01338 }
01339 
01340 bool ARMDAGToDAGISel::SelectT2AddrModeImm8Offset(SDNode *Op, SDValue N,
01341                                                  SDValue &OffImm){
01342   unsigned Opcode = Op->getOpcode();
01343   ISD::MemIndexedMode AM = (Opcode == ISD::LOAD)
01344     ? cast<LoadSDNode>(Op)->getAddressingMode()
01345     : cast<StoreSDNode>(Op)->getAddressingMode();
01346   int RHSC;
01347   if (isScaledConstantInRange(N, /*Scale=*/1, 0, 0x100, RHSC)) { // 8 bits.
01348     OffImm = ((AM == ISD::PRE_INC) || (AM == ISD::POST_INC))
01349       ? CurDAG->getTargetConstant(RHSC, MVT::i32)
01350       : CurDAG->getTargetConstant(-RHSC, MVT::i32);
01351     return true;
01352   }
01353 
01354   return false;
01355 }
01356 
01357 bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(SDValue N,
01358                                             SDValue &Base,
01359                                             SDValue &OffReg, SDValue &ShImm) {
01360   // (R - imm8) should be handled by t2LDRi8. The rest are handled by t2LDRi12.
01361   if (N.getOpcode() != ISD::ADD && !CurDAG->isBaseWithConstantOffset(N))
01362     return false;
01363 
01364   // Leave (R + imm12) for t2LDRi12, (R - imm8) for t2LDRi8.
01365   if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
01366     int RHSC = (int)RHS->getZExtValue();
01367     if (RHSC >= 0 && RHSC < 0x1000) // 12 bits (unsigned)
01368       return false;
01369     else if (RHSC < 0 && RHSC >= -255) // 8 bits
01370       return false;
01371   }
01372 
01373   // Look for (R + R) or (R + (R << [1,2,3])).
01374   unsigned ShAmt = 0;
01375   Base   = N.getOperand(0);
01376   OffReg = N.getOperand(1);
01377 
01378   // Swap if it is ((R << c) + R).
01379   ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(OffReg.getOpcode());
01380   if (ShOpcVal != ARM_AM::lsl) {
01381     ShOpcVal = ARM_AM::getShiftOpcForNode(Base.getOpcode());
01382     if (ShOpcVal == ARM_AM::lsl)
01383       std::swap(Base, OffReg);
01384   }
01385 
01386   if (ShOpcVal == ARM_AM::lsl) {
01387     // Check to see if the RHS of the shift is a constant, if not, we can't fold
01388     // it.
01389     if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(OffReg.getOperand(1))) {
01390       ShAmt = Sh->getZExtValue();
01391       if (ShAmt < 4 && isShifterOpProfitable(OffReg, ShOpcVal, ShAmt))
01392         OffReg = OffReg.getOperand(0);
01393       else {
01394         ShAmt = 0;
01395         ShOpcVal = ARM_AM::no_shift;
01396       }
01397     } else {
01398       ShOpcVal = ARM_AM::no_shift;
01399     }
01400   }
01401 
01402   ShImm = CurDAG->getTargetConstant(ShAmt, MVT::i32);
01403 
01404   return true;
01405 }
01406 
01407 bool ARMDAGToDAGISel::SelectT2AddrModeExclusive(SDValue N, SDValue &Base,
01408                                                 SDValue &OffImm) {
01409   // This *must* succeed since it's used for the irreplaceable ldrex and strex
01410   // instructions.
01411   Base = N;
01412   OffImm = CurDAG->getTargetConstant(0, MVT::i32);
01413 
01414   if (N.getOpcode() != ISD::ADD || !CurDAG->isBaseWithConstantOffset(N))
01415     return true;
01416 
01417   ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1));
01418   if (!RHS)
01419     return true;
01420 
01421   uint32_t RHSC = (int)RHS->getZExtValue();
01422   if (RHSC > 1020 || RHSC % 4 != 0)
01423     return true;
01424 
01425   Base = N.getOperand(0);
01426   if (Base.getOpcode() == ISD::FrameIndex) {
01427     int FI = cast<FrameIndexSDNode>(Base)->getIndex();
01428     Base = CurDAG->getTargetFrameIndex(FI, getTargetLowering()->getPointerTy());
01429   }
01430 
01431   OffImm = CurDAG->getTargetConstant(RHSC / 4, MVT::i32);
01432   return true;
01433 }
01434 
01435 //===--------------------------------------------------------------------===//
01436 
01437 /// getAL - Returns a ARMCC::AL immediate node.
01438 static inline SDValue getAL(SelectionDAG *CurDAG) {
01439   return CurDAG->getTargetConstant((uint64_t)ARMCC::AL, MVT::i32);
01440 }
01441 
01442 SDNode *ARMDAGToDAGISel::SelectARMIndexedLoad(SDNode *N) {
01443   LoadSDNode *LD = cast<LoadSDNode>(N);
01444   ISD::MemIndexedMode AM = LD->getAddressingMode();
01445   if (AM == ISD::UNINDEXED)
01446     return nullptr;
01447 
01448   EVT LoadedVT = LD->getMemoryVT();
01449   SDValue Offset, AMOpc;
01450   bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC);
01451   unsigned Opcode = 0;
01452   bool Match = false;
01453   if (LoadedVT == MVT::i32 && isPre &&
01454       SelectAddrMode2OffsetImmPre(N, LD->getOffset(), Offset, AMOpc)) {
01455     Opcode = ARM::LDR_PRE_IMM;
01456     Match = true;
01457   } else if (LoadedVT == MVT::i32 && !isPre &&
01458       SelectAddrMode2OffsetImm(N, LD->getOffset(), Offset, AMOpc)) {
01459     Opcode = ARM::LDR_POST_IMM;
01460     Match = true;
01461   } else if (LoadedVT == MVT::i32 &&
01462       SelectAddrMode2OffsetReg(N, LD->getOffset(), Offset, AMOpc)) {
01463     Opcode = isPre ? ARM::LDR_PRE_REG : ARM::LDR_POST_REG;
01464     Match = true;
01465 
01466   } else if (LoadedVT == MVT::i16 &&
01467              SelectAddrMode3Offset(N, LD->getOffset(), Offset, AMOpc)) {
01468     Match = true;
01469     Opcode = (LD->getExtensionType() == ISD::SEXTLOAD)
01470       ? (isPre ? ARM::LDRSH_PRE : ARM::LDRSH_POST)
01471       : (isPre ? ARM::LDRH_PRE : ARM::LDRH_POST);
01472   } else if (LoadedVT == MVT::i8 || LoadedVT == MVT::i1) {
01473     if (LD->getExtensionType() == ISD::SEXTLOAD) {
01474       if (SelectAddrMode3Offset(N, LD->getOffset(), Offset, AMOpc)) {
01475         Match = true;
01476         Opcode = isPre ? ARM::LDRSB_PRE : ARM::LDRSB_POST;
01477       }
01478     } else {
01479       if (isPre &&
01480           SelectAddrMode2OffsetImmPre(N, LD->getOffset(), Offset, AMOpc)) {
01481         Match = true;
01482         Opcode = ARM::LDRB_PRE_IMM;
01483       } else if (!isPre &&
01484                   SelectAddrMode2OffsetImm(N, LD->getOffset(), Offset, AMOpc)) {
01485         Match = true;
01486         Opcode = ARM::LDRB_POST_IMM;
01487       } else if (SelectAddrMode2OffsetReg(N, LD->getOffset(), Offset, AMOpc)) {
01488         Match = true;
01489         Opcode = isPre ? ARM::LDRB_PRE_REG : ARM::LDRB_POST_REG;
01490       }
01491     }
01492   }
01493 
01494   if (Match) {
01495     if (Opcode == ARM::LDR_PRE_IMM || Opcode == ARM::LDRB_PRE_IMM) {
01496       SDValue Chain = LD->getChain();
01497       SDValue Base = LD->getBasePtr();
01498       SDValue Ops[]= { Base, AMOpc, getAL(CurDAG),
01499                        CurDAG->getRegister(0, MVT::i32), Chain };
01500       return CurDAG->getMachineNode(Opcode, SDLoc(N), MVT::i32,
01501                                     MVT::i32, MVT::Other, Ops);
01502     } else {
01503       SDValue Chain = LD->getChain();
01504       SDValue Base = LD->getBasePtr();
01505       SDValue Ops[]= { Base, Offset, AMOpc, getAL(CurDAG),
01506                        CurDAG->getRegister(0, MVT::i32), Chain };
01507       return CurDAG->getMachineNode(Opcode, SDLoc(N), MVT::i32,
01508                                     MVT::i32, MVT::Other, Ops);
01509     }
01510   }
01511 
01512   return nullptr;
01513 }
01514 
01515 SDNode *ARMDAGToDAGISel::SelectT2IndexedLoad(SDNode *N) {
01516   LoadSDNode *LD = cast<LoadSDNode>(N);
01517   ISD::MemIndexedMode AM = LD->getAddressingMode();
01518   if (AM == ISD::UNINDEXED)
01519     return nullptr;
01520 
01521   EVT LoadedVT = LD->getMemoryVT();
01522   bool isSExtLd = LD->getExtensionType() == ISD::SEXTLOAD;
01523   SDValue Offset;
01524   bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC);
01525   unsigned Opcode = 0;
01526   bool Match = false;
01527   if (SelectT2AddrModeImm8Offset(N, LD->getOffset(), Offset)) {
01528     switch (LoadedVT.getSimpleVT().SimpleTy) {
01529     case MVT::i32:
01530       Opcode = isPre ? ARM::t2LDR_PRE : ARM::t2LDR_POST;
01531       break;
01532     case MVT::i16:
01533       if (isSExtLd)
01534         Opcode = isPre ? ARM::t2LDRSH_PRE : ARM::t2LDRSH_POST;
01535       else
01536         Opcode = isPre ? ARM::t2LDRH_PRE : ARM::t2LDRH_POST;
01537       break;
01538     case MVT::i8:
01539     case MVT::i1:
01540       if (isSExtLd)
01541         Opcode = isPre ? ARM::t2LDRSB_PRE : ARM::t2LDRSB_POST;
01542       else
01543         Opcode = isPre ? ARM::t2LDRB_PRE : ARM::t2LDRB_POST;
01544       break;
01545     default:
01546       return nullptr;
01547     }
01548     Match = true;
01549   }
01550 
01551   if (Match) {
01552     SDValue Chain = LD->getChain();
01553     SDValue Base = LD->getBasePtr();
01554     SDValue Ops[]= { Base, Offset, getAL(CurDAG),
01555                      CurDAG->getRegister(0, MVT::i32), Chain };
01556     return CurDAG->getMachineNode(Opcode, SDLoc(N), MVT::i32, MVT::i32,
01557                                   MVT::Other, Ops);
01558   }
01559 
01560   return nullptr;
01561 }
01562 
01563 /// \brief Form a GPRPair pseudo register from a pair of GPR regs.
01564 SDNode *ARMDAGToDAGISel::createGPRPairNode(EVT VT, SDValue V0, SDValue V1) {
01565   SDLoc dl(V0.getNode());
01566   SDValue RegClass =
01567     CurDAG->getTargetConstant(ARM::GPRPairRegClassID, MVT::i32);
01568   SDValue SubReg0 = CurDAG->getTargetConstant(ARM::gsub_0, MVT::i32);
01569   SDValue SubReg1 = CurDAG->getTargetConstant(ARM::gsub_1, MVT::i32);
01570   const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 };
01571   return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops);
01572 }
01573 
01574 /// \brief Form a D register from a pair of S registers.
01575 SDNode *ARMDAGToDAGISel::createSRegPairNode(EVT VT, SDValue V0, SDValue V1) {
01576   SDLoc dl(V0.getNode());
01577   SDValue RegClass =
01578     CurDAG->getTargetConstant(ARM::DPR_VFP2RegClassID, MVT::i32);
01579   SDValue SubReg0 = CurDAG->getTargetConstant(ARM::ssub_0, MVT::i32);
01580   SDValue SubReg1 = CurDAG->getTargetConstant(ARM::ssub_1, MVT::i32);
01581   const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 };
01582   return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops);
01583 }
01584 
01585 /// \brief Form a quad register from a pair of D registers.
01586 SDNode *ARMDAGToDAGISel::createDRegPairNode(EVT VT, SDValue V0, SDValue V1) {
01587   SDLoc dl(V0.getNode());
01588   SDValue RegClass = CurDAG->getTargetConstant(ARM::QPRRegClassID, MVT::i32);
01589   SDValue SubReg0 = CurDAG->getTargetConstant(ARM::dsub_0, MVT::i32);
01590   SDValue SubReg1 = CurDAG->getTargetConstant(ARM::dsub_1, MVT::i32);
01591   const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 };
01592   return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops);
01593 }
01594 
01595 /// \brief Form 4 consecutive D registers from a pair of Q registers.
01596 SDNode *ARMDAGToDAGISel::createQRegPairNode(EVT VT, SDValue V0, SDValue V1) {
01597   SDLoc dl(V0.getNode());
01598   SDValue RegClass = CurDAG->getTargetConstant(ARM::QQPRRegClassID, MVT::i32);
01599   SDValue SubReg0 = CurDAG->getTargetConstant(ARM::qsub_0, MVT::i32);
01600   SDValue SubReg1 = CurDAG->getTargetConstant(ARM::qsub_1, MVT::i32);
01601   const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1 };
01602   return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops);
01603 }
01604 
01605 /// \brief Form 4 consecutive S registers.
01606 SDNode *ARMDAGToDAGISel::createQuadSRegsNode(EVT VT, SDValue V0, SDValue V1,
01607                                    SDValue V2, SDValue V3) {
01608   SDLoc dl(V0.getNode());
01609   SDValue RegClass =
01610     CurDAG->getTargetConstant(ARM::QPR_VFP2RegClassID, MVT::i32);
01611   SDValue SubReg0 = CurDAG->getTargetConstant(ARM::ssub_0, MVT::i32);
01612   SDValue SubReg1 = CurDAG->getTargetConstant(ARM::ssub_1, MVT::i32);
01613   SDValue SubReg2 = CurDAG->getTargetConstant(ARM::ssub_2, MVT::i32);
01614   SDValue SubReg3 = CurDAG->getTargetConstant(ARM::ssub_3, MVT::i32);
01615   const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1,
01616                                     V2, SubReg2, V3, SubReg3 };
01617   return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops);
01618 }
01619 
01620 /// \brief Form 4 consecutive D registers.
01621 SDNode *ARMDAGToDAGISel::createQuadDRegsNode(EVT VT, SDValue V0, SDValue V1,
01622                                    SDValue V2, SDValue V3) {
01623   SDLoc dl(V0.getNode());
01624   SDValue RegClass = CurDAG->getTargetConstant(ARM::QQPRRegClassID, MVT::i32);
01625   SDValue SubReg0 = CurDAG->getTargetConstant(ARM::dsub_0, MVT::i32);
01626   SDValue SubReg1 = CurDAG->getTargetConstant(ARM::dsub_1, MVT::i32);
01627   SDValue SubReg2 = CurDAG->getTargetConstant(ARM::dsub_2, MVT::i32);
01628   SDValue SubReg3 = CurDAG->getTargetConstant(ARM::dsub_3, MVT::i32);
01629   const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1,
01630                                     V2, SubReg2, V3, SubReg3 };
01631   return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops);
01632 }
01633 
01634 /// \brief Form 4 consecutive Q registers.
01635 SDNode *ARMDAGToDAGISel::createQuadQRegsNode(EVT VT, SDValue V0, SDValue V1,
01636                                    SDValue V2, SDValue V3) {
01637   SDLoc dl(V0.getNode());
01638   SDValue RegClass = CurDAG->getTargetConstant(ARM::QQQQPRRegClassID, MVT::i32);
01639   SDValue SubReg0 = CurDAG->getTargetConstant(ARM::qsub_0, MVT::i32);
01640   SDValue SubReg1 = CurDAG->getTargetConstant(ARM::qsub_1, MVT::i32);
01641   SDValue SubReg2 = CurDAG->getTargetConstant(ARM::qsub_2, MVT::i32);
01642   SDValue SubReg3 = CurDAG->getTargetConstant(ARM::qsub_3, MVT::i32);
01643   const SDValue Ops[] = { RegClass, V0, SubReg0, V1, SubReg1,
01644                                     V2, SubReg2, V3, SubReg3 };
01645   return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, dl, VT, Ops);
01646 }
01647 
01648 /// GetVLDSTAlign - Get the alignment (in bytes) for the alignment operand
01649 /// of a NEON VLD or VST instruction.  The supported values depend on the
01650 /// number of registers being loaded.
01651 SDValue ARMDAGToDAGISel::GetVLDSTAlign(SDValue Align, unsigned NumVecs,
01652                                        bool is64BitVector) {
01653   unsigned NumRegs = NumVecs;
01654   if (!is64BitVector && NumVecs < 3)
01655     NumRegs *= 2;
01656 
01657   unsigned Alignment = cast<ConstantSDNode>(Align)->getZExtValue();
01658   if (Alignment >= 32 && NumRegs == 4)
01659     Alignment = 32;
01660   else if (Alignment >= 16 && (NumRegs == 2 || NumRegs == 4))
01661     Alignment = 16;
01662   else if (Alignment >= 8)
01663     Alignment = 8;
01664   else
01665     Alignment = 0;
01666 
01667   return CurDAG->getTargetConstant(Alignment, MVT::i32);
01668 }
01669 
01670 static bool isVLDfixed(unsigned Opc)
01671 {
01672   switch (Opc) {
01673   default: return false;
01674   case ARM::VLD1d8wb_fixed : return true;
01675   case ARM::VLD1d16wb_fixed : return true;
01676   case ARM::VLD1d64Qwb_fixed : return true;
01677   case ARM::VLD1d32wb_fixed : return true;
01678   case ARM::VLD1d64wb_fixed : return true;
01679   case ARM::VLD1d64TPseudoWB_fixed : return true;
01680   case ARM::VLD1d64QPseudoWB_fixed : return true;
01681   case ARM::VLD1q8wb_fixed : return true;
01682   case ARM::VLD1q16wb_fixed : return true;
01683   case ARM::VLD1q32wb_fixed : return true;
01684   case ARM::VLD1q64wb_fixed : return true;
01685   case ARM::VLD2d8wb_fixed : return true;
01686   case ARM::VLD2d16wb_fixed : return true;
01687   case ARM::VLD2d32wb_fixed : return true;
01688   case ARM::VLD2q8PseudoWB_fixed : return true;
01689   case ARM::VLD2q16PseudoWB_fixed : return true;
01690   case ARM::VLD2q32PseudoWB_fixed : return true;
01691   case ARM::VLD2DUPd8wb_fixed : return true;
01692   case ARM::VLD2DUPd16wb_fixed : return true;
01693   case ARM::VLD2DUPd32wb_fixed : return true;
01694   }
01695 }
01696 
01697 static bool isVSTfixed(unsigned Opc)
01698 {
01699   switch (Opc) {
01700   default: return false;
01701   case ARM::VST1d8wb_fixed : return true;
01702   case ARM::VST1d16wb_fixed : return true;
01703   case ARM::VST1d32wb_fixed : return true;
01704   case ARM::VST1d64wb_fixed : return true;
01705   case ARM::VST1q8wb_fixed : return true;
01706   case ARM::VST1q16wb_fixed : return true;
01707   case ARM::VST1q32wb_fixed : return true;
01708   case ARM::VST1q64wb_fixed : return true;
01709   case ARM::VST1d64TPseudoWB_fixed : return true;
01710   case ARM::VST1d64QPseudoWB_fixed : return true;
01711   case ARM::VST2d8wb_fixed : return true;
01712   case ARM::VST2d16wb_fixed : return true;
01713   case ARM::VST2d32wb_fixed : return true;
01714   case ARM::VST2q8PseudoWB_fixed : return true;
01715   case ARM::VST2q16PseudoWB_fixed : return true;
01716   case ARM::VST2q32PseudoWB_fixed : return true;
01717   }
01718 }
01719 
01720 // Get the register stride update opcode of a VLD/VST instruction that
01721 // is otherwise equivalent to the given fixed stride updating instruction.
01722 static unsigned getVLDSTRegisterUpdateOpcode(unsigned Opc) {
01723   assert((isVLDfixed(Opc) || isVSTfixed(Opc))
01724     && "Incorrect fixed stride updating instruction.");
01725   switch (Opc) {
01726   default: break;
01727   case ARM::VLD1d8wb_fixed: return ARM::VLD1d8wb_register;
01728   case ARM::VLD1d16wb_fixed: return ARM::VLD1d16wb_register;
01729   case ARM::VLD1d32wb_fixed: return ARM::VLD1d32wb_register;
01730   case ARM::VLD1d64wb_fixed: return ARM::VLD1d64wb_register;
01731   case ARM::VLD1q8wb_fixed: return ARM::VLD1q8wb_register;
01732   case ARM::VLD1q16wb_fixed: return ARM::VLD1q16wb_register;
01733   case ARM::VLD1q32wb_fixed: return ARM::VLD1q32wb_register;
01734   case ARM::VLD1q64wb_fixed: return ARM::VLD1q64wb_register;
01735   case ARM::VLD1d64Twb_fixed: return ARM::VLD1d64Twb_register;
01736   case ARM::VLD1d64Qwb_fixed: return ARM::VLD1d64Qwb_register;
01737   case ARM::VLD1d64TPseudoWB_fixed: return ARM::VLD1d64TPseudoWB_register;
01738   case ARM::VLD1d64QPseudoWB_fixed: return ARM::VLD1d64QPseudoWB_register;
01739 
01740   case ARM::VST1d8wb_fixed: return ARM::VST1d8wb_register;
01741   case ARM::VST1d16wb_fixed: return ARM::VST1d16wb_register;
01742   case ARM::VST1d32wb_fixed: return ARM::VST1d32wb_register;
01743   case ARM::VST1d64wb_fixed: return ARM::VST1d64wb_register;
01744   case ARM::VST1q8wb_fixed: return ARM::VST1q8wb_register;
01745   case ARM::VST1q16wb_fixed: return ARM::VST1q16wb_register;
01746   case ARM::VST1q32wb_fixed: return ARM::VST1q32wb_register;
01747   case ARM::VST1q64wb_fixed: return ARM::VST1q64wb_register;
01748   case ARM::VST1d64TPseudoWB_fixed: return ARM::VST1d64TPseudoWB_register;
01749   case ARM::VST1d64QPseudoWB_fixed: return ARM::VST1d64QPseudoWB_register;
01750 
01751   case ARM::VLD2d8wb_fixed: return ARM::VLD2d8wb_register;
01752   case ARM::VLD2d16wb_fixed: return ARM::VLD2d16wb_register;
01753   case ARM::VLD2d32wb_fixed: return ARM::VLD2d32wb_register;
01754   case ARM::VLD2q8PseudoWB_fixed: return ARM::VLD2q8PseudoWB_register;
01755   case ARM::VLD2q16PseudoWB_fixed: return ARM::VLD2q16PseudoWB_register;
01756   case ARM::VLD2q32PseudoWB_fixed: return ARM::VLD2q32PseudoWB_register;
01757 
01758   case ARM::VST2d8wb_fixed: return ARM::VST2d8wb_register;
01759   case ARM::VST2d16wb_fixed: return ARM::VST2d16wb_register;
01760   case ARM::VST2d32wb_fixed: return ARM::VST2d32wb_register;
01761   case ARM::VST2q8PseudoWB_fixed: return ARM::VST2q8PseudoWB_register;
01762   case ARM::VST2q16PseudoWB_fixed: return ARM::VST2q16PseudoWB_register;
01763   case ARM::VST2q32PseudoWB_fixed: return ARM::VST2q32PseudoWB_register;
01764 
01765   case ARM::VLD2DUPd8wb_fixed: return ARM::VLD2DUPd8wb_register;
01766   case ARM::VLD2DUPd16wb_fixed: return ARM::VLD2DUPd16wb_register;
01767   case ARM::VLD2DUPd32wb_fixed: return ARM::VLD2DUPd32wb_register;
01768   }
01769   return Opc; // If not one we handle, return it unchanged.
01770 }
01771 
01772 SDNode *ARMDAGToDAGISel::SelectVLD(SDNode *N, bool isUpdating, unsigned NumVecs,
01773                                    const uint16_t *DOpcodes,
01774                                    const uint16_t *QOpcodes0,
01775                                    const uint16_t *QOpcodes1) {
01776   assert(NumVecs >= 1 && NumVecs <= 4 && "VLD NumVecs out-of-range");
01777   SDLoc dl(N);
01778 
01779   SDValue MemAddr, Align;
01780   unsigned AddrOpIdx = isUpdating ? 1 : 2;
01781   if (!SelectAddrMode6(N, N->getOperand(AddrOpIdx), MemAddr, Align))
01782     return nullptr;
01783 
01784   SDValue Chain = N->getOperand(0);
01785   EVT VT = N->getValueType(0);
01786   bool is64BitVector = VT.is64BitVector();
01787   Align = GetVLDSTAlign(Align, NumVecs, is64BitVector);
01788 
01789   unsigned OpcodeIndex;
01790   switch (VT.getSimpleVT().SimpleTy) {
01791   default: llvm_unreachable("unhandled vld type");
01792     // Double-register operations:
01793   case MVT::v8i8:  OpcodeIndex = 0; break;
01794   case MVT::v4i16: OpcodeIndex = 1; break;
01795   case MVT::v2f32:
01796   case MVT::v2i32: OpcodeIndex = 2; break;
01797   case MVT::v1i64: OpcodeIndex = 3; break;
01798     // Quad-register operations:
01799   case MVT::v16i8: OpcodeIndex = 0; break;
01800   case MVT::v8i16: OpcodeIndex = 1; break;
01801   case MVT::v4f32:
01802   case MVT::v4i32: OpcodeIndex = 2; break;
01803   case MVT::v2i64: OpcodeIndex = 3;
01804     assert(NumVecs == 1 && "v2i64 type only supported for VLD1");
01805     break;
01806   }
01807 
01808   EVT ResTy;
01809   if (NumVecs == 1)
01810     ResTy = VT;
01811   else {
01812     unsigned ResTyElts = (NumVecs == 3) ? 4 : NumVecs;
01813     if (!is64BitVector)
01814       ResTyElts *= 2;
01815     ResTy = EVT::getVectorVT(*CurDAG->getContext(), MVT::i64, ResTyElts);
01816   }
01817   std::vector<EVT> ResTys;
01818   ResTys.push_back(ResTy);
01819   if (isUpdating)
01820     ResTys.push_back(MVT::i32);
01821   ResTys.push_back(MVT::Other);
01822 
01823   SDValue Pred = getAL(CurDAG);
01824   SDValue Reg0 = CurDAG->getRegister(0, MVT::i32);
01825   SDNode *VLd;
01826   SmallVector<SDValue, 7> Ops;
01827 
01828   // Double registers and VLD1/VLD2 quad registers are directly supported.
01829   if (is64BitVector || NumVecs <= 2) {
01830     unsigned Opc = (is64BitVector ? DOpcodes[OpcodeIndex] :
01831                     QOpcodes0[OpcodeIndex]);
01832     Ops.push_back(MemAddr);
01833     Ops.push_back(Align);
01834     if (isUpdating) {
01835       SDValue Inc = N->getOperand(AddrOpIdx + 1);
01836       // FIXME: VLD1/VLD2 fixed increment doesn't need Reg0. Remove the reg0
01837       // case entirely when the rest are updated to that form, too.
01838       if ((NumVecs <= 2) && !isa<ConstantSDNode>(Inc.getNode()))
01839         Opc = getVLDSTRegisterUpdateOpcode(Opc);
01840       // FIXME: We use a VLD1 for v1i64 even if the pseudo says vld2/3/4, so
01841       // check for that explicitly too. Horribly hacky, but temporary.
01842       if ((NumVecs > 2 && !isVLDfixed(Opc)) ||
01843           !isa<ConstantSDNode>(Inc.getNode()))
01844         Ops.push_back(isa<ConstantSDNode>(Inc.getNode()) ? Reg0 : Inc);
01845     }
01846     Ops.push_back(Pred);
01847     Ops.push_back(Reg0);
01848     Ops.push_back(Chain);
01849     VLd = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
01850 
01851   } else {
01852     // Otherwise, quad registers are loaded with two separate instructions,
01853     // where one loads the even registers and the other loads the odd registers.
01854     EVT AddrTy = MemAddr.getValueType();
01855 
01856     // Load the even subregs.  This is always an updating load, so that it
01857     // provides the address to the second load for the odd subregs.
01858     SDValue ImplDef =
01859       SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, ResTy), 0);
01860     const SDValue OpsA[] = { MemAddr, Align, Reg0, ImplDef, Pred, Reg0, Chain };
01861     SDNode *VLdA = CurDAG->getMachineNode(QOpcodes0[OpcodeIndex], dl,
01862                                           ResTy, AddrTy, MVT::Other, OpsA);
01863     Chain = SDValue(VLdA, 2);
01864 
01865     // Load the odd subregs.
01866     Ops.push_back(SDValue(VLdA, 1));
01867     Ops.push_back(Align);
01868     if (isUpdating) {
01869       SDValue Inc = N->getOperand(AddrOpIdx + 1);
01870       assert(isa<ConstantSDNode>(Inc.getNode()) &&
01871              "only constant post-increment update allowed for VLD3/4");
01872       (void)Inc;
01873       Ops.push_back(Reg0);
01874     }
01875     Ops.push_back(SDValue(VLdA, 0));
01876     Ops.push_back(Pred);
01877     Ops.push_back(Reg0);
01878     Ops.push_back(Chain);
01879     VLd = CurDAG->getMachineNode(QOpcodes1[OpcodeIndex], dl, ResTys, Ops);
01880   }
01881 
01882   // Transfer memoperands.
01883   MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
01884   MemOp[0] = cast<MemIntrinsicSDNode>(N)->getMemOperand();
01885   cast<MachineSDNode>(VLd)->setMemRefs(MemOp, MemOp + 1);
01886 
01887   if (NumVecs == 1)
01888     return VLd;
01889 
01890   // Extract out the subregisters.
01891   SDValue SuperReg = SDValue(VLd, 0);
01892   assert(ARM::dsub_7 == ARM::dsub_0+7 &&
01893          ARM::qsub_3 == ARM::qsub_0+3 && "Unexpected subreg numbering");
01894   unsigned Sub0 = (is64BitVector ? ARM::dsub_0 : ARM::qsub_0);
01895   for (unsigned Vec = 0; Vec < NumVecs; ++Vec)
01896     ReplaceUses(SDValue(N, Vec),
01897                 CurDAG->getTargetExtractSubreg(Sub0 + Vec, dl, VT, SuperReg));
01898   ReplaceUses(SDValue(N, NumVecs), SDValue(VLd, 1));
01899   if (isUpdating)
01900     ReplaceUses(SDValue(N, NumVecs + 1), SDValue(VLd, 2));
01901   return nullptr;
01902 }
01903 
01904 SDNode *ARMDAGToDAGISel::SelectVST(SDNode *N, bool isUpdating, unsigned NumVecs,
01905                                    const uint16_t *DOpcodes,
01906                                    const uint16_t *QOpcodes0,
01907                                    const uint16_t *QOpcodes1) {
01908   assert(NumVecs >= 1 && NumVecs <= 4 && "VST NumVecs out-of-range");
01909   SDLoc dl(N);
01910 
01911   SDValue MemAddr, Align;
01912   unsigned AddrOpIdx = isUpdating ? 1 : 2;
01913   unsigned Vec0Idx = 3; // AddrOpIdx + (isUpdating ? 2 : 1)
01914   if (!SelectAddrMode6(N, N->getOperand(AddrOpIdx), MemAddr, Align))
01915     return nullptr;
01916 
01917   MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
01918   MemOp[0] = cast<MemIntrinsicSDNode>(N)->getMemOperand();
01919 
01920   SDValue Chain = N->getOperand(0);
01921   EVT VT = N->getOperand(Vec0Idx).getValueType();
01922   bool is64BitVector = VT.is64BitVector();
01923   Align = GetVLDSTAlign(Align, NumVecs, is64BitVector);
01924 
01925   unsigned OpcodeIndex;
01926   switch (VT.getSimpleVT().SimpleTy) {
01927   default: llvm_unreachable("unhandled vst type");
01928     // Double-register operations:
01929   case MVT::v8i8:  OpcodeIndex = 0; break;
01930   case MVT::v4i16: OpcodeIndex = 1; break;
01931   case MVT::v2f32:
01932   case MVT::v2i32: OpcodeIndex = 2; break;
01933   case MVT::v1i64: OpcodeIndex = 3; break;
01934     // Quad-register operations:
01935   case MVT::v16i8: OpcodeIndex = 0; break;
01936   case MVT::v8i16: OpcodeIndex = 1; break;
01937   case MVT::v4f32:
01938   case MVT::v4i32: OpcodeIndex = 2; break;
01939   case MVT::v2i64: OpcodeIndex = 3;
01940     assert(NumVecs == 1 && "v2i64 type only supported for VST1");
01941     break;
01942   }
01943 
01944   std::vector<EVT> ResTys;
01945   if (isUpdating)
01946     ResTys.push_back(MVT::i32);
01947   ResTys.push_back(MVT::Other);
01948 
01949   SDValue Pred = getAL(CurDAG);
01950   SDValue Reg0 = CurDAG->getRegister(0, MVT::i32);
01951   SmallVector<SDValue, 7> Ops;
01952 
01953   // Double registers and VST1/VST2 quad registers are directly supported.
01954   if (is64BitVector || NumVecs <= 2) {
01955     SDValue SrcReg;
01956     if (NumVecs == 1) {
01957       SrcReg = N->getOperand(Vec0Idx);
01958     } else if (is64BitVector) {
01959       // Form a REG_SEQUENCE to force register allocation.
01960       SDValue V0 = N->getOperand(Vec0Idx + 0);
01961       SDValue V1 = N->getOperand(Vec0Idx + 1);
01962       if (NumVecs == 2)
01963         SrcReg = SDValue(createDRegPairNode(MVT::v2i64, V0, V1), 0);
01964       else {
01965         SDValue V2 = N->getOperand(Vec0Idx + 2);
01966         // If it's a vst3, form a quad D-register and leave the last part as
01967         // an undef.
01968         SDValue V3 = (NumVecs == 3)
01969           ? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,VT), 0)
01970           : N->getOperand(Vec0Idx + 3);
01971         SrcReg = SDValue(createQuadDRegsNode(MVT::v4i64, V0, V1, V2, V3), 0);
01972       }
01973     } else {
01974       // Form a QQ register.
01975       SDValue Q0 = N->getOperand(Vec0Idx);
01976       SDValue Q1 = N->getOperand(Vec0Idx + 1);
01977       SrcReg = SDValue(createQRegPairNode(MVT::v4i64, Q0, Q1), 0);
01978     }
01979 
01980     unsigned Opc = (is64BitVector ? DOpcodes[OpcodeIndex] :
01981                     QOpcodes0[OpcodeIndex]);
01982     Ops.push_back(MemAddr);
01983     Ops.push_back(Align);
01984     if (isUpdating) {
01985       SDValue Inc = N->getOperand(AddrOpIdx + 1);
01986       // FIXME: VST1/VST2 fixed increment doesn't need Reg0. Remove the reg0
01987       // case entirely when the rest are updated to that form, too.
01988       if (NumVecs <= 2 && !isa<ConstantSDNode>(Inc.getNode()))
01989         Opc = getVLDSTRegisterUpdateOpcode(Opc);
01990       // FIXME: We use a VST1 for v1i64 even if the pseudo says vld2/3/4, so
01991       // check for that explicitly too. Horribly hacky, but temporary.
01992       if  (!isa<ConstantSDNode>(Inc.getNode()))
01993         Ops.push_back(Inc);
01994       else if (NumVecs > 2 && !isVSTfixed(Opc))
01995         Ops.push_back(Reg0);
01996     }
01997     Ops.push_back(SrcReg);
01998     Ops.push_back(Pred);
01999     Ops.push_back(Reg0);
02000     Ops.push_back(Chain);
02001     SDNode *VSt = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
02002 
02003     // Transfer memoperands.
02004     cast<MachineSDNode>(VSt)->setMemRefs(MemOp, MemOp + 1);
02005 
02006     return VSt;
02007   }
02008 
02009   // Otherwise, quad registers are stored with two separate instructions,
02010   // where one stores the even registers and the other stores the odd registers.
02011 
02012   // Form the QQQQ REG_SEQUENCE.
02013   SDValue V0 = N->getOperand(Vec0Idx + 0);
02014   SDValue V1 = N->getOperand(Vec0Idx + 1);
02015   SDValue V2 = N->getOperand(Vec0Idx + 2);
02016   SDValue V3 = (NumVecs == 3)
02017     ? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, VT), 0)
02018     : N->getOperand(Vec0Idx + 3);
02019   SDValue RegSeq = SDValue(createQuadQRegsNode(MVT::v8i64, V0, V1, V2, V3), 0);
02020 
02021   // Store the even D registers.  This is always an updating store, so that it
02022   // provides the address to the second store for the odd subregs.
02023   const SDValue OpsA[] = { MemAddr, Align, Reg0, RegSeq, Pred, Reg0, Chain };
02024   SDNode *VStA = CurDAG->getMachineNode(QOpcodes0[OpcodeIndex], dl,
02025                                         MemAddr.getValueType(),
02026                                         MVT::Other, OpsA);
02027   cast<MachineSDNode>(VStA)->setMemRefs(MemOp, MemOp + 1);
02028   Chain = SDValue(VStA, 1);
02029 
02030   // Store the odd D registers.
02031   Ops.push_back(SDValue(VStA, 0));
02032   Ops.push_back(Align);
02033   if (isUpdating) {
02034     SDValue Inc = N->getOperand(AddrOpIdx + 1);
02035     assert(isa<ConstantSDNode>(Inc.getNode()) &&
02036            "only constant post-increment update allowed for VST3/4");
02037     (void)Inc;
02038     Ops.push_back(Reg0);
02039   }
02040   Ops.push_back(RegSeq);
02041   Ops.push_back(Pred);
02042   Ops.push_back(Reg0);
02043   Ops.push_back(Chain);
02044   SDNode *VStB = CurDAG->getMachineNode(QOpcodes1[OpcodeIndex], dl, ResTys,
02045                                         Ops);
02046   cast<MachineSDNode>(VStB)->setMemRefs(MemOp, MemOp + 1);
02047   return VStB;
02048 }
02049 
02050 SDNode *ARMDAGToDAGISel::SelectVLDSTLane(SDNode *N, bool IsLoad,
02051                                          bool isUpdating, unsigned NumVecs,
02052                                          const uint16_t *DOpcodes,
02053                                          const uint16_t *QOpcodes) {
02054   assert(NumVecs >=2 && NumVecs <= 4 && "VLDSTLane NumVecs out-of-range");
02055   SDLoc dl(N);
02056 
02057   SDValue MemAddr, Align;
02058   unsigned AddrOpIdx = isUpdating ? 1 : 2;
02059   unsigned Vec0Idx = 3; // AddrOpIdx + (isUpdating ? 2 : 1)
02060   if (!SelectAddrMode6(N, N->getOperand(AddrOpIdx), MemAddr, Align))
02061     return nullptr;
02062 
02063   MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
02064   MemOp[0] = cast<MemIntrinsicSDNode>(N)->getMemOperand();
02065 
02066   SDValue Chain = N->getOperand(0);
02067   unsigned Lane =
02068     cast<ConstantSDNode>(N->getOperand(Vec0Idx + NumVecs))->getZExtValue();
02069   EVT VT = N->getOperand(Vec0Idx).getValueType();
02070   bool is64BitVector = VT.is64BitVector();
02071 
02072   unsigned Alignment = 0;
02073   if (NumVecs != 3) {
02074     Alignment = cast<ConstantSDNode>(Align)->getZExtValue();
02075     unsigned NumBytes = NumVecs * VT.getVectorElementType().getSizeInBits()/8;
02076     if (Alignment > NumBytes)
02077       Alignment = NumBytes;
02078     if (Alignment < 8 && Alignment < NumBytes)
02079       Alignment = 0;
02080     // Alignment must be a power of two; make sure of that.
02081     Alignment = (Alignment & -Alignment);
02082     if (Alignment == 1)
02083       Alignment = 0;
02084   }
02085   Align = CurDAG->getTargetConstant(Alignment, MVT::i32);
02086 
02087   unsigned OpcodeIndex;
02088   switch (VT.getSimpleVT().SimpleTy) {
02089   default: llvm_unreachable("unhandled vld/vst lane type");
02090     // Double-register operations:
02091   case MVT::v8i8:  OpcodeIndex = 0; break;
02092   case MVT::v4i16: OpcodeIndex = 1; break;
02093   case MVT::v2f32:
02094   case MVT::v2i32: OpcodeIndex = 2; break;
02095     // Quad-register operations:
02096   case MVT::v8i16: OpcodeIndex = 0; break;
02097   case MVT::v4f32:
02098   case MVT::v4i32: OpcodeIndex = 1; break;
02099   }
02100 
02101   std::vector<EVT> ResTys;
02102   if (IsLoad) {
02103     unsigned ResTyElts = (NumVecs == 3) ? 4 : NumVecs;
02104     if (!is64BitVector)
02105       ResTyElts *= 2;
02106     ResTys.push_back(EVT::getVectorVT(*CurDAG->getContext(),
02107                                       MVT::i64, ResTyElts));
02108   }
02109   if (isUpdating)
02110     ResTys.push_back(MVT::i32);
02111   ResTys.push_back(MVT::Other);
02112 
02113   SDValue Pred = getAL(CurDAG);
02114   SDValue Reg0 = CurDAG->getRegister(0, MVT::i32);
02115 
02116   SmallVector<SDValue, 8> Ops;
02117   Ops.push_back(MemAddr);
02118   Ops.push_back(Align);
02119   if (isUpdating) {
02120     SDValue Inc = N->getOperand(AddrOpIdx + 1);
02121     Ops.push_back(isa<ConstantSDNode>(Inc.getNode()) ? Reg0 : Inc);
02122   }
02123 
02124   SDValue SuperReg;
02125   SDValue V0 = N->getOperand(Vec0Idx + 0);
02126   SDValue V1 = N->getOperand(Vec0Idx + 1);
02127   if (NumVecs == 2) {
02128     if (is64BitVector)
02129       SuperReg = SDValue(createDRegPairNode(MVT::v2i64, V0, V1), 0);
02130     else
02131       SuperReg = SDValue(createQRegPairNode(MVT::v4i64, V0, V1), 0);
02132   } else {
02133     SDValue V2 = N->getOperand(Vec0Idx + 2);
02134     SDValue V3 = (NumVecs == 3)
02135       ? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, VT), 0)
02136       : N->getOperand(Vec0Idx + 3);
02137     if (is64BitVector)
02138       SuperReg = SDValue(createQuadDRegsNode(MVT::v4i64, V0, V1, V2, V3), 0);
02139     else
02140       SuperReg = SDValue(createQuadQRegsNode(MVT::v8i64, V0, V1, V2, V3), 0);
02141   }
02142   Ops.push_back(SuperReg);
02143   Ops.push_back(getI32Imm(Lane));
02144   Ops.push_back(Pred);
02145   Ops.push_back(Reg0);
02146   Ops.push_back(Chain);
02147 
02148   unsigned Opc = (is64BitVector ? DOpcodes[OpcodeIndex] :
02149                                   QOpcodes[OpcodeIndex]);
02150   SDNode *VLdLn = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
02151   cast<MachineSDNode>(VLdLn)->setMemRefs(MemOp, MemOp + 1);
02152   if (!IsLoad)
02153     return VLdLn;
02154 
02155   // Extract the subregisters.
02156   SuperReg = SDValue(VLdLn, 0);
02157   assert(ARM::dsub_7 == ARM::dsub_0+7 &&
02158          ARM::qsub_3 == ARM::qsub_0+3 && "Unexpected subreg numbering");
02159   unsigned Sub0 = is64BitVector ? ARM::dsub_0 : ARM::qsub_0;
02160   for (unsigned Vec = 0; Vec < NumVecs; ++Vec)
02161     ReplaceUses(SDValue(N, Vec),
02162                 CurDAG->getTargetExtractSubreg(Sub0 + Vec, dl, VT, SuperReg));
02163   ReplaceUses(SDValue(N, NumVecs), SDValue(VLdLn, 1));
02164   if (isUpdating)
02165     ReplaceUses(SDValue(N, NumVecs + 1), SDValue(VLdLn, 2));
02166   return nullptr;
02167 }
02168 
02169 SDNode *ARMDAGToDAGISel::SelectVLDDup(SDNode *N, bool isUpdating,
02170                                       unsigned NumVecs,
02171                                       const uint16_t *Opcodes) {
02172   assert(NumVecs >=2 && NumVecs <= 4 && "VLDDup NumVecs out-of-range");
02173   SDLoc dl(N);
02174 
02175   SDValue MemAddr, Align;
02176   if (!SelectAddrMode6(N, N->getOperand(1), MemAddr, Align))
02177     return nullptr;
02178 
02179   MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
02180   MemOp[0] = cast<MemIntrinsicSDNode>(N)->getMemOperand();
02181 
02182   SDValue Chain = N->getOperand(0);
02183   EVT VT = N->getValueType(0);
02184 
02185   unsigned Alignment = 0;
02186   if (NumVecs != 3) {
02187     Alignment = cast<ConstantSDNode>(Align)->getZExtValue();
02188     unsigned NumBytes = NumVecs * VT.getVectorElementType().getSizeInBits()/8;
02189     if (Alignment > NumBytes)
02190       Alignment = NumBytes;
02191     if (Alignment < 8 && Alignment < NumBytes)
02192       Alignment = 0;
02193     // Alignment must be a power of two; make sure of that.
02194     Alignment = (Alignment & -Alignment);
02195     if (Alignment == 1)
02196       Alignment = 0;
02197   }
02198   Align = CurDAG->getTargetConstant(Alignment, MVT::i32);
02199 
02200   unsigned OpcodeIndex;
02201   switch (VT.getSimpleVT().SimpleTy) {
02202   default: llvm_unreachable("unhandled vld-dup type");
02203   case MVT::v8i8:  OpcodeIndex = 0; break;
02204   case MVT::v4i16: OpcodeIndex = 1; break;
02205   case MVT::v2f32:
02206   case MVT::v2i32: OpcodeIndex = 2; break;
02207   }
02208 
02209   SDValue Pred = getAL(CurDAG);
02210   SDValue Reg0 = CurDAG->getRegister(0, MVT::i32);
02211   SDValue SuperReg;
02212   unsigned Opc = Opcodes[OpcodeIndex];
02213   SmallVector<SDValue, 6> Ops;
02214   Ops.push_back(MemAddr);
02215   Ops.push_back(Align);
02216   if (isUpdating) {
02217     // fixed-stride update instructions don't have an explicit writeback
02218     // operand. It's implicit in the opcode itself.
02219     SDValue Inc = N->getOperand(2);
02220     if (!isa<ConstantSDNode>(Inc.getNode()))
02221       Ops.push_back(Inc);
02222     // FIXME: VLD3 and VLD4 haven't been updated to that form yet.
02223     else if (NumVecs > 2)
02224       Ops.push_back(Reg0);
02225   }
02226   Ops.push_back(Pred);
02227   Ops.push_back(Reg0);
02228   Ops.push_back(Chain);
02229 
02230   unsigned ResTyElts = (NumVecs == 3) ? 4 : NumVecs;
02231   std::vector<EVT> ResTys;
02232   ResTys.push_back(EVT::getVectorVT(*CurDAG->getContext(), MVT::i64,ResTyElts));
02233   if (isUpdating)
02234     ResTys.push_back(MVT::i32);
02235   ResTys.push_back(MVT::Other);
02236   SDNode *VLdDup = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
02237   cast<MachineSDNode>(VLdDup)->setMemRefs(MemOp, MemOp + 1);
02238   SuperReg = SDValue(VLdDup, 0);
02239 
02240   // Extract the subregisters.
02241   assert(ARM::dsub_7 == ARM::dsub_0+7 && "Unexpected subreg numbering");
02242   unsigned SubIdx = ARM::dsub_0;
02243   for (unsigned Vec = 0; Vec < NumVecs; ++Vec)
02244     ReplaceUses(SDValue(N, Vec),
02245                 CurDAG->getTargetExtractSubreg(SubIdx+Vec, dl, VT, SuperReg));
02246   ReplaceUses(SDValue(N, NumVecs), SDValue(VLdDup, 1));
02247   if (isUpdating)
02248     ReplaceUses(SDValue(N, NumVecs + 1), SDValue(VLdDup, 2));
02249   return nullptr;
02250 }
02251 
02252 SDNode *ARMDAGToDAGISel::SelectVTBL(SDNode *N, bool IsExt, unsigned NumVecs,
02253                                     unsigned Opc) {
02254   assert(NumVecs >= 2 && NumVecs <= 4 && "VTBL NumVecs out-of-range");
02255   SDLoc dl(N);
02256   EVT VT = N->getValueType(0);
02257   unsigned FirstTblReg = IsExt ? 2 : 1;
02258 
02259   // Form a REG_SEQUENCE to force register allocation.
02260   SDValue RegSeq;
02261   SDValue V0 = N->getOperand(FirstTblReg + 0);
02262   SDValue V1 = N->getOperand(FirstTblReg + 1);
02263   if (NumVecs == 2)
02264     RegSeq = SDValue(createDRegPairNode(MVT::v16i8, V0, V1), 0);
02265   else {
02266     SDValue V2 = N->getOperand(FirstTblReg + 2);
02267     // If it's a vtbl3, form a quad D-register and leave the last part as
02268     // an undef.
02269     SDValue V3 = (NumVecs == 3)
02270       ? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, VT), 0)
02271       : N->getOperand(FirstTblReg + 3);
02272     RegSeq = SDValue(createQuadDRegsNode(MVT::v4i64, V0, V1, V2, V3), 0);
02273   }
02274 
02275   SmallVector<SDValue, 6> Ops;
02276   if (IsExt)
02277     Ops.push_back(N->getOperand(1));
02278   Ops.push_back(RegSeq);
02279   Ops.push_back(N->getOperand(FirstTblReg + NumVecs));
02280   Ops.push_back(getAL(CurDAG)); // predicate
02281   Ops.push_back(CurDAG->getRegister(0, MVT::i32)); // predicate register
02282   return CurDAG->getMachineNode(Opc, dl, VT, Ops);
02283 }
02284 
02285 SDNode *ARMDAGToDAGISel::SelectV6T2BitfieldExtractOp(SDNode *N,
02286                                                      bool isSigned) {
02287   if (!Subtarget->hasV6T2Ops())
02288     return nullptr;
02289 
02290   unsigned Opc = isSigned
02291     ? (Subtarget->isThumb() ? ARM::t2SBFX : ARM::SBFX)
02292     : (Subtarget->isThumb() ? ARM::t2UBFX : ARM::UBFX);
02293 
02294   // For unsigned extracts, check for a shift right and mask
02295   unsigned And_imm = 0;
02296   if (N->getOpcode() == ISD::AND) {
02297     if (isOpcWithIntImmediate(N, ISD::AND, And_imm)) {
02298 
02299       // The immediate is a mask of the low bits iff imm & (imm+1) == 0
02300       if (And_imm & (And_imm + 1))
02301         return nullptr;
02302 
02303       unsigned Srl_imm = 0;
02304       if (isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::SRL,
02305                                 Srl_imm)) {
02306         assert(Srl_imm > 0 && Srl_imm < 32 && "bad amount in shift node!");
02307 
02308         // Note: The width operand is encoded as width-1.
02309         unsigned Width = CountTrailingOnes_32(And_imm) - 1;
02310         unsigned LSB = Srl_imm;
02311 
02312         SDValue Reg0 = CurDAG->getRegister(0, MVT::i32);
02313 
02314         if ((LSB + Width + 1) == N->getValueType(0).getSizeInBits()) {
02315           // It's cheaper to use a right shift to extract the top bits.
02316           if (Subtarget->isThumb()) {
02317             Opc = isSigned ? ARM::t2ASRri : ARM::t2LSRri;
02318             SDValue Ops[] = { N->getOperand(0).getOperand(0),
02319                               CurDAG->getTargetConstant(LSB, MVT::i32),
02320                               getAL(CurDAG), Reg0, Reg0 };
02321             return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops);
02322           }
02323 
02324           // ARM models shift instructions as MOVsi with shifter operand.
02325           ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(ISD::SRL);
02326           SDValue ShOpc =
02327             CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, LSB),
02328                                       MVT::i32);
02329           SDValue Ops[] = { N->getOperand(0).getOperand(0), ShOpc,
02330                             getAL(CurDAG), Reg0, Reg0 };
02331           return CurDAG->SelectNodeTo(N, ARM::MOVsi, MVT::i32, Ops);
02332         }
02333 
02334         SDValue Ops[] = { N->getOperand(0).getOperand(0),
02335                           CurDAG->getTargetConstant(LSB, MVT::i32),
02336                           CurDAG->getTargetConstant(Width, MVT::i32),
02337                           getAL(CurDAG), Reg0 };
02338         return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops);
02339       }
02340     }
02341     return nullptr;
02342   }
02343 
02344   // Otherwise, we're looking for a shift of a shift
02345   unsigned Shl_imm = 0;
02346   if (isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::SHL, Shl_imm)) {
02347     assert(Shl_imm > 0 && Shl_imm < 32 && "bad amount in shift node!");
02348     unsigned Srl_imm = 0;
02349     if (isInt32Immediate(N->getOperand(1), Srl_imm)) {
02350       assert(Srl_imm > 0 && Srl_imm < 32 && "bad amount in shift node!");
02351       // Note: The width operand is encoded as width-1.
02352       unsigned Width = 32 - Srl_imm - 1;
02353       int LSB = Srl_imm - Shl_imm;
02354       if (LSB < 0)
02355         return nullptr;
02356       SDValue Reg0 = CurDAG->getRegister(0, MVT::i32);
02357       SDValue Ops[] = { N->getOperand(0).getOperand(0),
02358                         CurDAG->getTargetConstant(LSB, MVT::i32),
02359                         CurDAG->getTargetConstant(Width, MVT::i32),
02360                         getAL(CurDAG), Reg0 };
02361       return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops);
02362     }
02363   }
02364 
02365   if (N->getOpcode() == ISD::SIGN_EXTEND_INREG) {
02366     unsigned Width = cast<VTSDNode>(N->getOperand(1))->getVT().getSizeInBits();
02367     unsigned LSB = 0;
02368     if (!isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::SRL, LSB) &&
02369         !isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::SRA, LSB))
02370       return nullptr;
02371 
02372     if (LSB + Width > 32)
02373       return nullptr;
02374 
02375     SDValue Reg0 = CurDAG->getRegister(0, MVT::i32);
02376     SDValue Ops[] = { N->getOperand(0).getOperand(0),
02377                       CurDAG->getTargetConstant(LSB, MVT::i32),
02378                       CurDAG->getTargetConstant(Width - 1, MVT::i32),
02379                       getAL(CurDAG), Reg0 };
02380     return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops);
02381   }
02382 
02383   return nullptr;
02384 }
02385 
02386 /// Target-specific DAG combining for ISD::XOR.
02387 /// Target-independent combining lowers SELECT_CC nodes of the form
02388 /// select_cc setg[ge] X,  0,  X, -X
02389 /// select_cc setgt    X, -1,  X, -X
02390 /// select_cc setl[te] X,  0, -X,  X
02391 /// select_cc setlt    X,  1, -X,  X
02392 /// which represent Integer ABS into:
02393 /// Y = sra (X, size(X)-1); xor (add (X, Y), Y)
02394 /// ARM instruction selection detects the latter and matches it to
02395 /// ARM::ABS or ARM::t2ABS machine node.
02396 SDNode *ARMDAGToDAGISel::SelectABSOp(SDNode *N){
02397   SDValue XORSrc0 = N->getOperand(0);
02398   SDValue XORSrc1 = N->getOperand(1);
02399   EVT VT = N->getValueType(0);
02400 
02401   if (Subtarget->isThumb1Only())
02402     return nullptr;
02403 
02404   if (XORSrc0.getOpcode() != ISD::ADD || XORSrc1.getOpcode() != ISD::SRA)
02405     return nullptr;
02406 
02407   SDValue ADDSrc0 = XORSrc0.getOperand(0);
02408   SDValue ADDSrc1 = XORSrc0.getOperand(1);
02409   SDValue SRASrc0 = XORSrc1.getOperand(0);
02410   SDValue SRASrc1 = XORSrc1.getOperand(1);
02411   ConstantSDNode *SRAConstant =  dyn_cast<ConstantSDNode>(SRASrc1);
02412   EVT XType = SRASrc0.getValueType();
02413   unsigned Size = XType.getSizeInBits() - 1;
02414 
02415   if (ADDSrc1 == XORSrc1 && ADDSrc0 == SRASrc0 &&
02416       XType.isInteger() && SRAConstant != nullptr &&
02417       Size == SRAConstant->getZExtValue()) {
02418     unsigned Opcode = Subtarget->isThumb2() ? ARM::t2ABS : ARM::ABS;
02419     return CurDAG->SelectNodeTo(N, Opcode, VT, ADDSrc0);
02420   }
02421 
02422   return nullptr;
02423 }
02424 
02425 SDNode *ARMDAGToDAGISel::SelectConcatVector(SDNode *N) {
02426   // The only time a CONCAT_VECTORS operation can have legal types is when
02427   // two 64-bit vectors are concatenated to a 128-bit vector.
02428   EVT VT = N->getValueType(0);
02429   if (!VT.is128BitVector() || N->getNumOperands() != 2)
02430     llvm_unreachable("unexpected CONCAT_VECTORS");
02431   return createDRegPairNode(VT, N->getOperand(0), N->getOperand(1));
02432 }
02433 
02434 SDNode *ARMDAGToDAGISel::Select(SDNode *N) {
02435   SDLoc dl(N);
02436 
02437   if (N->isMachineOpcode()) {
02438     N->setNodeId(-1);
02439     return nullptr;   // Already selected.
02440   }
02441 
02442   switch (N->getOpcode()) {
02443   default: break;
02444   case ISD::INLINEASM: {
02445     SDNode *ResNode = SelectInlineAsm(N);
02446     if (ResNode)
02447       return ResNode;
02448     break;
02449   }
02450   case ISD::XOR: {
02451     // Select special operations if XOR node forms integer ABS pattern
02452     SDNode *ResNode = SelectABSOp(N);
02453     if (ResNode)
02454       return ResNode;
02455     // Other cases are autogenerated.
02456     break;
02457   }
02458   case ISD::Constant: {
02459     unsigned Val = cast<ConstantSDNode>(N)->getZExtValue();
02460     bool UseCP = true;
02461     if (Subtarget->useMovt(*MF))
02462       // Thumb2-aware targets have the MOVT instruction, so all immediates can
02463       // be done with MOV + MOVT, at worst.
02464       UseCP = false;
02465     else {
02466       if (Subtarget->isThumb()) {
02467         UseCP = (Val > 255 &&                                  // MOV
02468                  ~Val > 255 &&                                 // MOV + MVN
02469                  !ARM_AM::isThumbImmShiftedVal(Val) &&         // MOV + LSL
02470                  !(Subtarget->hasV6T2Ops() && Val <= 0xffff)); // MOVW
02471       } else
02472         UseCP = (ARM_AM::getSOImmVal(Val) == -1 &&             // MOV
02473                  ARM_AM::getSOImmVal(~Val) == -1 &&            // MVN
02474                  !ARM_AM::isSOImmTwoPartVal(Val) &&            // two instrs.
02475                  !(Subtarget->hasV6T2Ops() && Val <= 0xffff)); // MOVW
02476     }
02477 
02478     if (UseCP) {
02479       SDValue CPIdx =
02480         CurDAG->getTargetConstantPool(ConstantInt::get(
02481                                   Type::getInt32Ty(*CurDAG->getContext()), Val),
02482                                       getTargetLowering()->getPointerTy());
02483 
02484       SDNode *ResNode;
02485       if (Subtarget->isThumb()) {
02486         SDValue Pred = getAL(CurDAG);
02487         SDValue PredReg = CurDAG->getRegister(0, MVT::i32);
02488         SDValue Ops[] = { CPIdx, Pred, PredReg, CurDAG->getEntryNode() };
02489         ResNode = CurDAG->getMachineNode(ARM::tLDRpci, dl, MVT::i32, MVT::Other,
02490                                          Ops);
02491       } else {
02492         SDValue Ops[] = {
02493           CPIdx,
02494           CurDAG->getTargetConstant(0, MVT::i32),
02495           getAL(CurDAG),
02496           CurDAG->getRegister(0, MVT::i32),
02497           CurDAG->getEntryNode()
02498         };
02499         ResNode=CurDAG->getMachineNode(ARM::LDRcp, dl, MVT::i32, MVT::Other,
02500                                        Ops);
02501       }
02502       ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
02503       return nullptr;
02504     }
02505 
02506     // Other cases are autogenerated.
02507     break;
02508   }
02509   case ISD::FrameIndex: {
02510     // Selects to ADDri FI, 0 which in turn will become ADDri SP, imm.
02511     int FI = cast<FrameIndexSDNode>(N)->getIndex();
02512     SDValue TFI = CurDAG->getTargetFrameIndex(FI,
02513                                            getTargetLowering()->getPointerTy());
02514     if (Subtarget->isThumb1Only()) {
02515       SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0, MVT::i32),
02516                         getAL(CurDAG), CurDAG->getRegister(0, MVT::i32) };
02517       return CurDAG->SelectNodeTo(N, ARM::tADDrSPi, MVT::i32, Ops);
02518     } else {
02519       unsigned Opc = ((Subtarget->isThumb() && Subtarget->hasThumb2()) ?
02520                       ARM::t2ADDri : ARM::ADDri);
02521       SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0, MVT::i32),
02522                         getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
02523                         CurDAG->getRegister(0, MVT::i32) };
02524       return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops);
02525     }
02526   }
02527   case ISD::SRL:
02528     if (SDNode *I = SelectV6T2BitfieldExtractOp(N, false))
02529       return I;
02530     break;
02531   case ISD::SIGN_EXTEND_INREG:
02532   case ISD::SRA:
02533     if (SDNode *I = SelectV6T2BitfieldExtractOp(N, true))
02534       return I;
02535     break;
02536   case ISD::MUL:
02537     if (Subtarget->isThumb1Only())
02538       break;
02539     if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1))) {
02540       unsigned RHSV = C->getZExtValue();
02541       if (!RHSV) break;
02542       if (isPowerOf2_32(RHSV-1)) {  // 2^n+1?
02543         unsigned ShImm = Log2_32(RHSV-1);
02544         if (ShImm >= 32)
02545           break;
02546         SDValue V = N->getOperand(0);
02547         ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, ShImm);
02548         SDValue ShImmOp = CurDAG->getTargetConstant(ShImm, MVT::i32);
02549         SDValue Reg0 = CurDAG->getRegister(0, MVT::i32);
02550         if (Subtarget->isThumb()) {
02551           SDValue Ops[] = { V, V, ShImmOp, getAL(CurDAG), Reg0, Reg0 };
02552           return CurDAG->SelectNodeTo(N, ARM::t2ADDrs, MVT::i32, Ops);
02553         } else {
02554           SDValue Ops[] = { V, V, Reg0, ShImmOp, getAL(CurDAG), Reg0, Reg0 };
02555           return CurDAG->SelectNodeTo(N, ARM::ADDrsi, MVT::i32, Ops);
02556         }
02557       }
02558       if (isPowerOf2_32(RHSV+1)) {  // 2^n-1?
02559         unsigned ShImm = Log2_32(RHSV+1);
02560         if (ShImm >= 32)
02561           break;
02562         SDValue V = N->getOperand(0);
02563         ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, ShImm);
02564         SDValue ShImmOp = CurDAG->getTargetConstant(ShImm, MVT::i32);
02565         SDValue Reg0 = CurDAG->getRegister(0, MVT::i32);
02566         if (Subtarget->isThumb()) {
02567           SDValue Ops[] = { V, V, ShImmOp, getAL(CurDAG), Reg0, Reg0 };
02568           return CurDAG->SelectNodeTo(N, ARM::t2RSBrs, MVT::i32, Ops);
02569         } else {
02570           SDValue Ops[] = { V, V, Reg0, ShImmOp, getAL(CurDAG), Reg0, Reg0 };
02571           return CurDAG->SelectNodeTo(N, ARM::RSBrsi, MVT::i32, Ops);
02572         }
02573       }
02574     }
02575     break;
02576   case ISD::AND: {
02577     // Check for unsigned bitfield extract
02578     if (SDNode *I = SelectV6T2BitfieldExtractOp(N, false))
02579       return I;
02580 
02581     // (and (or x, c2), c1) and top 16-bits of c1 and c2 match, lower 16-bits
02582     // of c1 are 0xffff, and lower 16-bit of c2 are 0. That is, the top 16-bits
02583     // are entirely contributed by c2 and lower 16-bits are entirely contributed
02584     // by x. That's equal to (or (and x, 0xffff), (and c1, 0xffff0000)).
02585     // Select it to: "movt x, ((c1 & 0xffff) >> 16)
02586     EVT VT = N->getValueType(0);
02587     if (VT != MVT::i32)
02588       break;
02589     unsigned Opc = (Subtarget->isThumb() && Subtarget->hasThumb2())
02590       ? ARM::t2MOVTi16
02591       : (Subtarget->hasV6T2Ops() ? ARM::MOVTi16 : 0);
02592     if (!Opc)
02593       break;
02594     SDValue N0 = N->getOperand(0), N1 = N->getOperand(1);
02595     ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
02596     if (!N1C)
02597       break;
02598     if (N0.getOpcode() == ISD::OR && N0.getNode()->hasOneUse()) {
02599       SDValue N2 = N0.getOperand(1);
02600       ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2);
02601       if (!N2C)
02602         break;
02603       unsigned N1CVal = N1C->getZExtValue();
02604       unsigned N2CVal = N2C->getZExtValue();
02605       if ((N1CVal & 0xffff0000U) == (N2CVal & 0xffff0000U) &&
02606           (N1CVal & 0xffffU) == 0xffffU &&
02607           (N2CVal & 0xffffU) == 0x0U) {
02608         SDValue Imm16 = CurDAG->getTargetConstant((N2CVal & 0xFFFF0000U) >> 16,
02609                                                   MVT::i32);
02610         SDValue Ops[] = { N0.getOperand(0), Imm16,
02611                           getAL(CurDAG), CurDAG->getRegister(0, MVT::i32) };
02612         return CurDAG->getMachineNode(Opc, dl, VT, Ops);
02613       }
02614     }
02615     break;
02616   }
02617   case ARMISD::VMOVRRD:
02618     return CurDAG->getMachineNode(ARM::VMOVRRD, dl, MVT::i32, MVT::i32,
02619                                   N->getOperand(0), getAL(CurDAG),
02620                                   CurDAG->getRegister(0, MVT::i32));
02621   case ISD::UMUL_LOHI: {
02622     if (Subtarget->isThumb1Only())
02623       break;
02624     if (Subtarget->isThumb()) {
02625       SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
02626                         getAL(CurDAG), CurDAG->getRegister(0, MVT::i32) };
02627       return CurDAG->getMachineNode(ARM::t2UMULL, dl, MVT::i32, MVT::i32, Ops);
02628     } else {
02629       SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
02630                         getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
02631                         CurDAG->getRegister(0, MVT::i32) };
02632       return CurDAG->getMachineNode(Subtarget->hasV6Ops() ?
02633                                     ARM::UMULL : ARM::UMULLv5,
02634                                     dl, MVT::i32, MVT::i32, Ops);
02635     }
02636   }
02637   case ISD::SMUL_LOHI: {
02638     if (Subtarget->isThumb1Only())
02639       break;
02640     if (Subtarget->isThumb()) {
02641       SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
02642                         getAL(CurDAG), CurDAG->getRegister(0, MVT::i32) };
02643       return CurDAG->getMachineNode(ARM::t2SMULL, dl, MVT::i32, MVT::i32, Ops);
02644     } else {
02645       SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
02646                         getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
02647                         CurDAG->getRegister(0, MVT::i32) };
02648       return CurDAG->getMachineNode(Subtarget->hasV6Ops() ?
02649                                     ARM::SMULL : ARM::SMULLv5,
02650                                     dl, MVT::i32, MVT::i32, Ops);
02651     }
02652   }
02653   case ARMISD::UMLAL:{
02654     if (Subtarget->isThumb()) {
02655       SDValue Ops[] = { N->getOperand(0), N->getOperand(1), N->getOperand(2),
02656                         N->getOperand(3), getAL(CurDAG),
02657                         CurDAG->getRegister(0, MVT::i32)};
02658       return CurDAG->getMachineNode(ARM::t2UMLAL, dl, MVT::i32, MVT::i32, Ops);
02659     }else{
02660       SDValue Ops[] = { N->getOperand(0), N->getOperand(1), N->getOperand(2),
02661                         N->getOperand(3), getAL(CurDAG),
02662                         CurDAG->getRegister(0, MVT::i32),
02663                         CurDAG->getRegister(0, MVT::i32) };
02664       return CurDAG->getMachineNode(Subtarget->hasV6Ops() ?
02665                                       ARM::UMLAL : ARM::UMLALv5,
02666                                       dl, MVT::i32, MVT::i32, Ops);
02667     }
02668   }
02669   case ARMISD::SMLAL:{
02670     if (Subtarget->isThumb()) {
02671       SDValue Ops[] = { N->getOperand(0), N->getOperand(1), N->getOperand(2),
02672                         N->getOperand(3), getAL(CurDAG),
02673                         CurDAG->getRegister(0, MVT::i32)};
02674       return CurDAG->getMachineNode(ARM::t2SMLAL, dl, MVT::i32, MVT::i32, Ops);
02675     }else{
02676       SDValue Ops[] = { N->getOperand(0), N->getOperand(1), N->getOperand(2),
02677                         N->getOperand(3), getAL(CurDAG),
02678                         CurDAG->getRegister(0, MVT::i32),
02679                         CurDAG->getRegister(0, MVT::i32) };
02680       return CurDAG->getMachineNode(Subtarget->hasV6Ops() ?
02681                                       ARM::SMLAL : ARM::SMLALv5,
02682                                       dl, MVT::i32, MVT::i32, Ops);
02683     }
02684   }
02685   case ISD::LOAD: {
02686     SDNode *ResNode = nullptr;
02687     if (Subtarget->isThumb() && Subtarget->hasThumb2())
02688       ResNode = SelectT2IndexedLoad(N);
02689     else
02690       ResNode = SelectARMIndexedLoad(N);
02691     if (ResNode)
02692       return ResNode;
02693     // Other cases are autogenerated.
02694     break;
02695   }
02696   case ARMISD::BRCOND: {
02697     // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc)
02698     // Emits: (Bcc:void (bb:Other):$dst, (imm:i32):$cc)
02699     // Pattern complexity = 6  cost = 1  size = 0
02700 
02701     // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc)
02702     // Emits: (tBcc:void (bb:Other):$dst, (imm:i32):$cc)
02703     // Pattern complexity = 6  cost = 1  size = 0
02704 
02705     // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc)
02706     // Emits: (t2Bcc:void (bb:Other):$dst, (imm:i32):$cc)
02707     // Pattern complexity = 6  cost = 1  size = 0
02708 
02709     unsigned Opc = Subtarget->isThumb() ?
02710       ((Subtarget->hasThumb2()) ? ARM::t2Bcc : ARM::tBcc) : ARM::Bcc;
02711     SDValue Chain = N->getOperand(0);
02712     SDValue N1 = N->getOperand(1);
02713     SDValue N2 = N->getOperand(2);
02714     SDValue N3 = N->getOperand(3);
02715     SDValue InFlag = N->getOperand(4);
02716     assert(N1.getOpcode() == ISD::BasicBlock);
02717     assert(N2.getOpcode() == ISD::Constant);
02718     assert(N3.getOpcode() == ISD::Register);
02719 
02720     SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned)
02721                                cast<ConstantSDNode>(N2)->getZExtValue()),
02722                                MVT::i32);
02723     SDValue Ops[] = { N1, Tmp2, N3, Chain, InFlag };
02724     SDNode *ResNode = CurDAG->getMachineNode(Opc, dl, MVT::Other,
02725                                              MVT::Glue, Ops);
02726     Chain = SDValue(ResNode, 0);
02727     if (N->getNumValues() == 2) {
02728       InFlag = SDValue(ResNode, 1);
02729       ReplaceUses(SDValue(N, 1), InFlag);
02730     }
02731     ReplaceUses(SDValue(N, 0),
02732                 SDValue(Chain.getNode(), Chain.getResNo()));
02733     return nullptr;
02734   }
02735   case ARMISD::VZIP: {
02736     unsigned Opc = 0;
02737     EVT VT = N->getValueType(0);
02738     switch (VT.getSimpleVT().SimpleTy) {
02739     default: return nullptr;
02740     case MVT::v8i8:  Opc = ARM::VZIPd8; break;
02741     case MVT::v4i16: Opc = ARM::VZIPd16; break;
02742     case MVT::v2f32:
02743     // vzip.32 Dd, Dm is a pseudo-instruction expanded to vtrn.32 Dd, Dm.
02744     case MVT::v2i32: Opc = ARM::VTRNd32; break;
02745     case MVT::v16i8: Opc = ARM::VZIPq8; break;
02746     case MVT::v8i16: Opc = ARM::VZIPq16; break;
02747     case MVT::v4f32:
02748     case MVT::v4i32: Opc = ARM::VZIPq32; break;
02749     }
02750     SDValue Pred = getAL(CurDAG);
02751     SDValue PredReg = CurDAG->getRegister(0, MVT::i32);
02752     SDValue Ops[] = { N->getOperand(0), N->getOperand(1), Pred, PredReg };
02753     return CurDAG->getMachineNode(Opc, dl, VT, VT, Ops);
02754   }
02755   case ARMISD::VUZP: {
02756     unsigned Opc = 0;
02757     EVT VT = N->getValueType(0);
02758     switch (VT.getSimpleVT().SimpleTy) {
02759     default: return nullptr;
02760     case MVT::v8i8:  Opc = ARM::VUZPd8; break;
02761     case MVT::v4i16: Opc = ARM::VUZPd16; break;
02762     case MVT::v2f32:
02763     // vuzp.32 Dd, Dm is a pseudo-instruction expanded to vtrn.32 Dd, Dm.
02764     case MVT::v2i32: Opc = ARM::VTRNd32; break;
02765     case MVT::v16i8: Opc = ARM::VUZPq8; break;
02766     case MVT::v8i16: Opc = ARM::VUZPq16; break;
02767     case MVT::v4f32:
02768     case MVT::v4i32: Opc = ARM::VUZPq32; break;
02769     }
02770     SDValue Pred = getAL(CurDAG);
02771     SDValue PredReg = CurDAG->getRegister(0, MVT::i32);
02772     SDValue Ops[] = { N->getOperand(0), N->getOperand(1), Pred, PredReg };
02773     return CurDAG->getMachineNode(Opc, dl, VT, VT, Ops);
02774   }
02775   case ARMISD::VTRN: {
02776     unsigned Opc = 0;
02777     EVT VT = N->getValueType(0);
02778     switch (VT.getSimpleVT().SimpleTy) {
02779     default: return nullptr;
02780     case MVT::v8i8:  Opc = ARM::VTRNd8; break;
02781     case MVT::v4i16: Opc = ARM::VTRNd16; break;
02782     case MVT::v2f32:
02783     case MVT::v2i32: Opc = ARM::VTRNd32; break;
02784     case MVT::v16i8: Opc = ARM::VTRNq8; break;
02785     case MVT::v8i16: Opc = ARM::VTRNq16; break;
02786     case MVT::v4f32:
02787     case MVT::v4i32: Opc = ARM::VTRNq32; break;
02788     }
02789     SDValue Pred = getAL(CurDAG);
02790     SDValue PredReg = CurDAG->getRegister(0, MVT::i32);
02791     SDValue Ops[] = { N->getOperand(0), N->getOperand(1), Pred, PredReg };
02792     return CurDAG->getMachineNode(Opc, dl, VT, VT, Ops);
02793   }
02794   case ARMISD::BUILD_VECTOR: {
02795     EVT VecVT = N->getValueType(0);
02796     EVT EltVT = VecVT.getVectorElementType();
02797     unsigned NumElts = VecVT.getVectorNumElements();
02798     if (EltVT == MVT::f64) {
02799       assert(NumElts == 2 && "unexpected type for BUILD_VECTOR");
02800       return createDRegPairNode(VecVT, N->getOperand(0), N->getOperand(1));
02801     }
02802     assert(EltVT == MVT::f32 && "unexpected type for BUILD_VECTOR");
02803     if (NumElts == 2)
02804       return createSRegPairNode(VecVT, N->getOperand(0), N->getOperand(1));
02805     assert(NumElts == 4 && "unexpected type for BUILD_VECTOR");
02806     return createQuadSRegsNode(VecVT, N->getOperand(0), N->getOperand(1),
02807                      N->getOperand(2), N->getOperand(3));
02808   }
02809 
02810   case ARMISD::VLD2DUP: {
02811     static const uint16_t Opcodes[] = { ARM::VLD2DUPd8, ARM::VLD2DUPd16,
02812                                         ARM::VLD2DUPd32 };
02813     return SelectVLDDup(N, false, 2, Opcodes);
02814   }
02815 
02816   case ARMISD::VLD3DUP: {
02817     static const uint16_t Opcodes[] = { ARM::VLD3DUPd8Pseudo,
02818                                         ARM::VLD3DUPd16Pseudo,
02819                                         ARM::VLD3DUPd32Pseudo };
02820     return SelectVLDDup(N, false, 3, Opcodes);
02821   }
02822 
02823   case ARMISD::VLD4DUP: {
02824     static const uint16_t Opcodes[] = { ARM::VLD4DUPd8Pseudo,
02825                                         ARM::VLD4DUPd16Pseudo,
02826                                         ARM::VLD4DUPd32Pseudo };
02827     return SelectVLDDup(N, false, 4, Opcodes);
02828   }
02829 
02830   case ARMISD::VLD2DUP_UPD: {
02831     static const uint16_t Opcodes[] = { ARM::VLD2DUPd8wb_fixed,
02832                                         ARM::VLD2DUPd16wb_fixed,
02833                                         ARM::VLD2DUPd32wb_fixed };
02834     return SelectVLDDup(N, true, 2, Opcodes);
02835   }
02836 
02837   case ARMISD::VLD3DUP_UPD: {
02838     static const uint16_t Opcodes[] = { ARM::VLD3DUPd8Pseudo_UPD,
02839                                         ARM::VLD3DUPd16Pseudo_UPD,
02840                                         ARM::VLD3DUPd32Pseudo_UPD };
02841     return SelectVLDDup(N, true, 3, Opcodes);
02842   }
02843 
02844   case ARMISD::VLD4DUP_UPD: {
02845     static const uint16_t Opcodes[] = { ARM::VLD4DUPd8Pseudo_UPD,
02846                                         ARM::VLD4DUPd16Pseudo_UPD,
02847                                         ARM::VLD4DUPd32Pseudo_UPD };
02848     return SelectVLDDup(N, true, 4, Opcodes);
02849   }
02850 
02851   case ARMISD::VLD1_UPD: {
02852     static const uint16_t DOpcodes[] = { ARM::VLD1d8wb_fixed,
02853                                          ARM::VLD1d16wb_fixed,
02854                                          ARM::VLD1d32wb_fixed,
02855                                          ARM::VLD1d64wb_fixed };
02856     static const uint16_t QOpcodes[] = { ARM::VLD1q8wb_fixed,
02857                                          ARM::VLD1q16wb_fixed,
02858                                          ARM::VLD1q32wb_fixed,
02859                                          ARM::VLD1q64wb_fixed };
02860     return SelectVLD(N, true, 1, DOpcodes, QOpcodes, nullptr);
02861   }
02862 
02863   case ARMISD::VLD2_UPD: {
02864     static const uint16_t DOpcodes[] = { ARM::VLD2d8wb_fixed,
02865                                          ARM::VLD2d16wb_fixed,
02866                                          ARM::VLD2d32wb_fixed,
02867                                          ARM::VLD1q64wb_fixed};
02868     static const uint16_t QOpcodes[] = { ARM::VLD2q8PseudoWB_fixed,
02869                                          ARM::VLD2q16PseudoWB_fixed,
02870                                          ARM::VLD2q32PseudoWB_fixed };
02871     return SelectVLD(N, true, 2, DOpcodes, QOpcodes, nullptr);
02872   }
02873 
02874   case ARMISD::VLD3_UPD: {
02875     static const uint16_t DOpcodes[] = { ARM::VLD3d8Pseudo_UPD,
02876                                          ARM::VLD3d16Pseudo_UPD,
02877                                          ARM::VLD3d32Pseudo_UPD,
02878                                          ARM::VLD1d64TPseudoWB_fixed};
02879     static const uint16_t QOpcodes0[] = { ARM::VLD3q8Pseudo_UPD,
02880                                           ARM::VLD3q16Pseudo_UPD,
02881                                           ARM::VLD3q32Pseudo_UPD };
02882     static const uint16_t QOpcodes1[] = { ARM::VLD3q8oddPseudo_UPD,
02883                                           ARM::VLD3q16oddPseudo_UPD,
02884                                           ARM::VLD3q32oddPseudo_UPD };
02885     return SelectVLD(N, true, 3, DOpcodes, QOpcodes0, QOpcodes1);
02886   }
02887 
02888   case ARMISD::VLD4_UPD: {
02889     static const uint16_t DOpcodes[] = { ARM::VLD4d8Pseudo_UPD,
02890                                          ARM::VLD4d16Pseudo_UPD,
02891                                          ARM::VLD4d32Pseudo_UPD,
02892                                          ARM::VLD1d64QPseudoWB_fixed};
02893     static const uint16_t QOpcodes0[] = { ARM::VLD4q8Pseudo_UPD,
02894                                           ARM::VLD4q16Pseudo_UPD,
02895                                           ARM::VLD4q32Pseudo_UPD };
02896     static const uint16_t QOpcodes1[] = { ARM::VLD4q8oddPseudo_UPD,
02897                                           ARM::VLD4q16oddPseudo_UPD,
02898                                           ARM::VLD4q32oddPseudo_UPD };
02899     return SelectVLD(N, true, 4, DOpcodes, QOpcodes0, QOpcodes1);
02900   }
02901 
02902   case ARMISD::VLD2LN_UPD: {
02903     static const uint16_t DOpcodes[] = { ARM::VLD2LNd8Pseudo_UPD,
02904                                          ARM::VLD2LNd16Pseudo_UPD,
02905                                          ARM::VLD2LNd32Pseudo_UPD };
02906     static const uint16_t QOpcodes[] = { ARM::VLD2LNq16Pseudo_UPD,
02907                                          ARM::VLD2LNq32Pseudo_UPD };
02908     return SelectVLDSTLane(N, true, true, 2, DOpcodes, QOpcodes);
02909   }
02910 
02911   case ARMISD::VLD3LN_UPD: {
02912     static const uint16_t DOpcodes[] = { ARM::VLD3LNd8Pseudo_UPD,
02913                                          ARM::VLD3LNd16Pseudo_UPD,
02914                                          ARM::VLD3LNd32Pseudo_UPD };
02915     static const uint16_t QOpcodes[] = { ARM::VLD3LNq16Pseudo_UPD,
02916                                          ARM::VLD3LNq32Pseudo_UPD };
02917     return SelectVLDSTLane(N, true, true, 3, DOpcodes, QOpcodes);
02918   }
02919 
02920   case ARMISD::VLD4LN_UPD: {
02921     static const uint16_t DOpcodes[] = { ARM::VLD4LNd8Pseudo_UPD,
02922                                          ARM::VLD4LNd16Pseudo_UPD,
02923                                          ARM::VLD4LNd32Pseudo_UPD };
02924     static const uint16_t QOpcodes[] = { ARM::VLD4LNq16Pseudo_UPD,
02925                                          ARM::VLD4LNq32Pseudo_UPD };
02926     return SelectVLDSTLane(N, true, true, 4, DOpcodes, QOpcodes);
02927   }
02928 
02929   case ARMISD::VST1_UPD: {
02930     static const uint16_t DOpcodes[] = { ARM::VST1d8wb_fixed,
02931                                          ARM::VST1d16wb_fixed,
02932                                          ARM::VST1d32wb_fixed,
02933                                          ARM::VST1d64wb_fixed };
02934     static const uint16_t QOpcodes[] = { ARM::VST1q8wb_fixed,
02935                                          ARM::VST1q16wb_fixed,
02936                                          ARM::VST1q32wb_fixed,
02937                                          ARM::VST1q64wb_fixed };
02938     return SelectVST(N, true, 1, DOpcodes, QOpcodes, nullptr);
02939   }
02940 
02941   case ARMISD::VST2_UPD: {
02942     static const uint16_t DOpcodes[] = { ARM::VST2d8wb_fixed,
02943                                          ARM::VST2d16wb_fixed,
02944                                          ARM::VST2d32wb_fixed,
02945                                          ARM::VST1q64wb_fixed};
02946     static const uint16_t QOpcodes[] = { ARM::VST2q8PseudoWB_fixed,
02947                                          ARM::VST2q16PseudoWB_fixed,
02948                                          ARM::VST2q32PseudoWB_fixed };
02949     return SelectVST(N, true, 2, DOpcodes, QOpcodes, nullptr);
02950   }
02951 
02952   case ARMISD::VST3_UPD: {
02953     static const uint16_t DOpcodes[] = { ARM::VST3d8Pseudo_UPD,
02954                                          ARM::VST3d16Pseudo_UPD,
02955                                          ARM::VST3d32Pseudo_UPD,
02956                                          ARM::VST1d64TPseudoWB_fixed};
02957     static const uint16_t QOpcodes0[] = { ARM::VST3q8Pseudo_UPD,
02958                                           ARM::VST3q16Pseudo_UPD,
02959                                           ARM::VST3q32Pseudo_UPD };
02960     static const uint16_t QOpcodes1[] = { ARM::VST3q8oddPseudo_UPD,
02961                                           ARM::VST3q16oddPseudo_UPD,
02962                                           ARM::VST3q32oddPseudo_UPD };
02963     return SelectVST(N, true, 3, DOpcodes, QOpcodes0, QOpcodes1);
02964   }
02965 
02966   case ARMISD::VST4_UPD: {
02967     static const uint16_t DOpcodes[] = { ARM::VST4d8Pseudo_UPD,
02968                                          ARM::VST4d16Pseudo_UPD,
02969                                          ARM::VST4d32Pseudo_UPD,
02970                                          ARM::VST1d64QPseudoWB_fixed};
02971     static const uint16_t QOpcodes0[] = { ARM::VST4q8Pseudo_UPD,
02972                                           ARM::VST4q16Pseudo_UPD,
02973                                           ARM::VST4q32Pseudo_UPD };
02974     static const uint16_t QOpcodes1[] = { ARM::VST4q8oddPseudo_UPD,
02975                                           ARM::VST4q16oddPseudo_UPD,
02976                                           ARM::VST4q32oddPseudo_UPD };
02977     return SelectVST(N, true, 4, DOpcodes, QOpcodes0, QOpcodes1);
02978   }
02979 
02980   case ARMISD::VST2LN_UPD: {
02981     static const uint16_t DOpcodes[] = { ARM::VST2LNd8Pseudo_UPD,
02982                                          ARM::VST2LNd16Pseudo_UPD,
02983                                          ARM::VST2LNd32Pseudo_UPD };
02984     static const uint16_t QOpcodes[] = { ARM::VST2LNq16Pseudo_UPD,
02985                                          ARM::VST2LNq32Pseudo_UPD };
02986     return SelectVLDSTLane(N, false, true, 2, DOpcodes, QOpcodes);
02987   }
02988 
02989   case ARMISD::VST3LN_UPD: {
02990     static const uint16_t DOpcodes[] = { ARM::VST3LNd8Pseudo_UPD,
02991                                          ARM::VST3LNd16Pseudo_UPD,
02992                                          ARM::VST3LNd32Pseudo_UPD };
02993     static const uint16_t QOpcodes[] = { ARM::VST3LNq16Pseudo_UPD,
02994                                          ARM::VST3LNq32Pseudo_UPD };
02995     return SelectVLDSTLane(N, false, true, 3, DOpcodes, QOpcodes);
02996   }
02997 
02998   case ARMISD::VST4LN_UPD: {
02999     static const uint16_t DOpcodes[] = { ARM::VST4LNd8Pseudo_UPD,
03000                                          ARM::VST4LNd16Pseudo_UPD,
03001                                          ARM::VST4LNd32Pseudo_UPD };
03002     static const uint16_t QOpcodes[] = { ARM::VST4LNq16Pseudo_UPD,
03003                                          ARM::VST4LNq32Pseudo_UPD };
03004     return SelectVLDSTLane(N, false, true, 4, DOpcodes, QOpcodes);
03005   }
03006 
03007   case ISD::INTRINSIC_VOID:
03008   case ISD::INTRINSIC_W_CHAIN: {
03009     unsigned IntNo = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
03010     switch (IntNo) {
03011     default:
03012       break;
03013 
03014     case Intrinsic::arm_ldaexd:
03015     case Intrinsic::arm_ldrexd: {
03016       SDLoc dl(N);
03017       SDValue Chain = N->getOperand(0);
03018       SDValue MemAddr = N->getOperand(2);
03019       bool isThumb = Subtarget->isThumb() && Subtarget->hasThumb2();
03020 
03021       bool IsAcquire = IntNo == Intrinsic::arm_ldaexd;
03022       unsigned NewOpc = isThumb ? (IsAcquire ? ARM::t2LDAEXD : ARM::t2LDREXD)
03023                                 : (IsAcquire ? ARM::LDAEXD : ARM::LDREXD);
03024 
03025       // arm_ldrexd returns a i64 value in {i32, i32}
03026       std::vector<EVT> ResTys;
03027       if (isThumb) {
03028         ResTys.push_back(MVT::i32);
03029         ResTys.push_back(MVT::i32);
03030       } else
03031         ResTys.push_back(MVT::Untyped);
03032       ResTys.push_back(MVT::Other);
03033 
03034       // Place arguments in the right order.
03035       SmallVector<SDValue, 7> Ops;
03036       Ops.push_back(MemAddr);
03037       Ops.push_back(getAL(CurDAG));
03038       Ops.push_back(CurDAG->getRegister(0, MVT::i32));
03039       Ops.push_back(Chain);
03040       SDNode *Ld = CurDAG->getMachineNode(NewOpc, dl, ResTys, Ops);
03041       // Transfer memoperands.
03042       MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
03043       MemOp[0] = cast<MemIntrinsicSDNode>(N)->getMemOperand();
03044       cast<MachineSDNode>(Ld)->setMemRefs(MemOp, MemOp + 1);
03045 
03046       // Remap uses.
03047       SDValue OutChain = isThumb ? SDValue(Ld, 2) : SDValue(Ld, 1);
03048       if (!SDValue(N, 0).use_empty()) {
03049         SDValue Result;
03050         if (isThumb)
03051           Result = SDValue(Ld, 0);
03052         else {
03053           SDValue SubRegIdx = CurDAG->getTargetConstant(ARM::gsub_0, MVT::i32);
03054           SDNode *ResNode = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG,
03055               dl, MVT::i32, SDValue(Ld, 0), SubRegIdx);
03056           Result = SDValue(ResNode,0);
03057         }
03058         ReplaceUses(SDValue(N, 0), Result);
03059       }
03060       if (!SDValue(N, 1).use_empty()) {
03061         SDValue Result;
03062         if (isThumb)
03063           Result = SDValue(Ld, 1);
03064         else {
03065           SDValue SubRegIdx = CurDAG->getTargetConstant(ARM::gsub_1, MVT::i32);
03066           SDNode *ResNode = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG,
03067               dl, MVT::i32, SDValue(Ld, 0), SubRegIdx);
03068           Result = SDValue(ResNode,0);
03069         }
03070         ReplaceUses(SDValue(N, 1), Result);
03071       }
03072       ReplaceUses(SDValue(N, 2), OutChain);
03073       return nullptr;
03074     }
03075     case Intrinsic::arm_stlexd:
03076     case Intrinsic::arm_strexd: {
03077       SDLoc dl(N);
03078       SDValue Chain = N->getOperand(0);
03079       SDValue Val0 = N->getOperand(2);
03080       SDValue Val1 = N->getOperand(3);
03081       SDValue MemAddr = N->getOperand(4);
03082 
03083       // Store exclusive double return a i32 value which is the return status
03084       // of the issued store.
03085       EVT ResTys[] = { MVT::i32, MVT::Other };
03086 
03087       bool isThumb = Subtarget->isThumb() && Subtarget->hasThumb2();
03088       // Place arguments in the right order.
03089       SmallVector<SDValue, 7> Ops;
03090       if (isThumb) {
03091         Ops.push_back(Val0);
03092         Ops.push_back(Val1);
03093       } else
03094         // arm_strexd uses GPRPair.
03095         Ops.push_back(SDValue(createGPRPairNode(MVT::Untyped, Val0, Val1), 0));
03096       Ops.push_back(MemAddr);
03097       Ops.push_back(getAL(CurDAG));
03098       Ops.push_back(CurDAG->getRegister(0, MVT::i32));
03099       Ops.push_back(Chain);
03100 
03101       bool IsRelease = IntNo == Intrinsic::arm_stlexd;
03102       unsigned NewOpc = isThumb ? (IsRelease ? ARM::t2STLEXD : ARM::t2STREXD)
03103                                 : (IsRelease ? ARM::STLEXD : ARM::STREXD);
03104 
03105       SDNode *St = CurDAG->getMachineNode(NewOpc, dl, ResTys, Ops);
03106       // Transfer memoperands.
03107       MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
03108       MemOp[0] = cast<MemIntrinsicSDNode>(N)->getMemOperand();
03109       cast<MachineSDNode>(St)->setMemRefs(MemOp, MemOp + 1);
03110 
03111       return St;
03112     }
03113 
03114     case Intrinsic::arm_neon_vld1: {
03115       static const uint16_t DOpcodes[] = { ARM::VLD1d8, ARM::VLD1d16,
03116                                            ARM::VLD1d32, ARM::VLD1d64 };
03117       static const uint16_t QOpcodes[] = { ARM::VLD1q8, ARM::VLD1q16,
03118                                            ARM::VLD1q32, ARM::VLD1q64};
03119       return SelectVLD(N, false, 1, DOpcodes, QOpcodes, nullptr);
03120     }
03121 
03122     case Intrinsic::arm_neon_vld2: {
03123       static const uint16_t DOpcodes[] = { ARM::VLD2d8, ARM::VLD2d16,
03124                                            ARM::VLD2d32, ARM::VLD1q64 };
03125       static const uint16_t QOpcodes[] = { ARM::VLD2q8Pseudo, ARM::VLD2q16Pseudo,
03126                                            ARM::VLD2q32Pseudo };
03127       return SelectVLD(N, false, 2, DOpcodes, QOpcodes, nullptr);
03128     }
03129 
03130     case Intrinsic::arm_neon_vld3: {
03131       static const uint16_t DOpcodes[] = { ARM::VLD3d8Pseudo,
03132                                            ARM::VLD3d16Pseudo,
03133                                            ARM::VLD3d32Pseudo,
03134                                            ARM::VLD1d64TPseudo };
03135       static const uint16_t QOpcodes0[] = { ARM::VLD3q8Pseudo_UPD,
03136                                             ARM::VLD3q16Pseudo_UPD,
03137                                             ARM::VLD3q32Pseudo_UPD };
03138       static const uint16_t QOpcodes1[] = { ARM::VLD3q8oddPseudo,
03139                                             ARM::VLD3q16oddPseudo,
03140                                             ARM::VLD3q32oddPseudo };
03141       return SelectVLD(N, false, 3, DOpcodes, QOpcodes0, QOpcodes1);
03142     }
03143 
03144     case Intrinsic::arm_neon_vld4: {
03145       static const uint16_t DOpcodes[] = { ARM::VLD4d8Pseudo,
03146                                            ARM::VLD4d16Pseudo,
03147                                            ARM::VLD4d32Pseudo,
03148                                            ARM::VLD1d64QPseudo };
03149       static const uint16_t QOpcodes0[] = { ARM::VLD4q8Pseudo_UPD,
03150                                             ARM::VLD4q16Pseudo_UPD,
03151                                             ARM::VLD4q32Pseudo_UPD };
03152       static const uint16_t QOpcodes1[] = { ARM::VLD4q8oddPseudo,
03153                                             ARM::VLD4q16oddPseudo,
03154                                             ARM::VLD4q32oddPseudo };
03155       return SelectVLD(N, false, 4, DOpcodes, QOpcodes0, QOpcodes1);
03156     }
03157 
03158     case Intrinsic::arm_neon_vld2lane: {
03159       static const uint16_t DOpcodes[] = { ARM::VLD2LNd8Pseudo,
03160                                            ARM::VLD2LNd16Pseudo,
03161                                            ARM::VLD2LNd32Pseudo };
03162       static const uint16_t QOpcodes[] = { ARM::VLD2LNq16Pseudo,
03163                                            ARM::VLD2LNq32Pseudo };
03164       return SelectVLDSTLane(N, true, false, 2, DOpcodes, QOpcodes);
03165     }
03166 
03167     case Intrinsic::arm_neon_vld3lane: {
03168       static const uint16_t DOpcodes[] = { ARM::VLD3LNd8Pseudo,
03169                                            ARM::VLD3LNd16Pseudo,
03170                                            ARM::VLD3LNd32Pseudo };
03171       static const uint16_t QOpcodes[] = { ARM::VLD3LNq16Pseudo,
03172                                            ARM::VLD3LNq32Pseudo };
03173       return SelectVLDSTLane(N, true, false, 3, DOpcodes, QOpcodes);
03174     }
03175 
03176     case Intrinsic::arm_neon_vld4lane: {
03177       static const uint16_t DOpcodes[] = { ARM::VLD4LNd8Pseudo,
03178                                            ARM::VLD4LNd16Pseudo,
03179                                            ARM::VLD4LNd32Pseudo };
03180       static const uint16_t QOpcodes[] = { ARM::VLD4LNq16Pseudo,
03181                                            ARM::VLD4LNq32Pseudo };
03182       return SelectVLDSTLane(N, true, false, 4, DOpcodes, QOpcodes);
03183     }
03184 
03185     case Intrinsic::arm_neon_vst1: {
03186       static const uint16_t DOpcodes[] = { ARM::VST1d8, ARM::VST1d16,
03187                                            ARM::VST1d32, ARM::VST1d64 };
03188       static const uint16_t QOpcodes[] = { ARM::VST1q8, ARM::VST1q16,
03189                                            ARM::VST1q32, ARM::VST1q64 };
03190       return SelectVST(N, false, 1, DOpcodes, QOpcodes, nullptr);
03191     }
03192 
03193     case Intrinsic::arm_neon_vst2: {
03194       static const uint16_t DOpcodes[] = { ARM::VST2d8, ARM::VST2d16,
03195                                            ARM::VST2d32, ARM::VST1q64 };
03196       static uint16_t QOpcodes[] = { ARM::VST2q8Pseudo, ARM::VST2q16Pseudo,
03197                                      ARM::VST2q32Pseudo };
03198       return SelectVST(N, false, 2, DOpcodes, QOpcodes, nullptr);
03199     }
03200 
03201     case Intrinsic::arm_neon_vst3: {
03202       static const uint16_t DOpcodes[] = { ARM::VST3d8Pseudo,
03203                                            ARM::VST3d16Pseudo,
03204                                            ARM::VST3d32Pseudo,
03205                                            ARM::VST1d64TPseudo };
03206       static const uint16_t QOpcodes0[] = { ARM::VST3q8Pseudo_UPD,
03207                                             ARM::VST3q16Pseudo_UPD,
03208                                             ARM::VST3q32Pseudo_UPD };
03209       static const uint16_t QOpcodes1[] = { ARM::VST3q8oddPseudo,
03210                                             ARM::VST3q16oddPseudo,
03211                                             ARM::VST3q32oddPseudo };
03212       return SelectVST(N, false, 3, DOpcodes, QOpcodes0, QOpcodes1);
03213     }
03214 
03215     case Intrinsic::arm_neon_vst4: {
03216       static const uint16_t DOpcodes[] = { ARM::VST4d8Pseudo,
03217                                            ARM::VST4d16Pseudo,
03218                                            ARM::VST4d32Pseudo,
03219                                            ARM::VST1d64QPseudo };
03220       static const uint16_t QOpcodes0[] = { ARM::VST4q8Pseudo_UPD,
03221                                             ARM::VST4q16Pseudo_UPD,
03222                                             ARM::VST4q32Pseudo_UPD };
03223       static const uint16_t QOpcodes1[] = { ARM::VST4q8oddPseudo,
03224                                             ARM::VST4q16oddPseudo,
03225                                             ARM::VST4q32oddPseudo };
03226       return SelectVST(N, false, 4, DOpcodes, QOpcodes0, QOpcodes1);
03227     }
03228 
03229     case Intrinsic::arm_neon_vst2lane: {
03230       static const uint16_t DOpcodes[] = { ARM::VST2LNd8Pseudo,
03231                                            ARM::VST2LNd16Pseudo,
03232                                            ARM::VST2LNd32Pseudo };
03233       static const uint16_t QOpcodes[] = { ARM::VST2LNq16Pseudo,
03234                                            ARM::VST2LNq32Pseudo };
03235       return SelectVLDSTLane(N, false, false, 2, DOpcodes, QOpcodes);
03236     }
03237 
03238     case Intrinsic::arm_neon_vst3lane: {
03239       static const uint16_t DOpcodes[] = { ARM::VST3LNd8Pseudo,
03240                                            ARM::VST3LNd16Pseudo,
03241                                            ARM::VST3LNd32Pseudo };
03242       static const uint16_t QOpcodes[] = { ARM::VST3LNq16Pseudo,
03243                                            ARM::VST3LNq32Pseudo };
03244       return SelectVLDSTLane(N, false, false, 3, DOpcodes, QOpcodes);
03245     }
03246 
03247     case Intrinsic::arm_neon_vst4lane: {
03248       static const uint16_t DOpcodes[] = { ARM::VST4LNd8Pseudo,
03249                                            ARM::VST4LNd16Pseudo,
03250                                            ARM::VST4LNd32Pseudo };
03251       static const uint16_t QOpcodes[] = { ARM::VST4LNq16Pseudo,
03252                                            ARM::VST4LNq32Pseudo };
03253       return SelectVLDSTLane(N, false, false, 4, DOpcodes, QOpcodes);
03254     }
03255     }
03256     break;
03257   }
03258 
03259   case ISD::INTRINSIC_WO_CHAIN: {
03260     unsigned IntNo = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
03261     switch (IntNo) {
03262     default:
03263       break;
03264 
03265     case Intrinsic::arm_neon_vtbl2:
03266       return SelectVTBL(N, false, 2, ARM::VTBL2);
03267     case Intrinsic::arm_neon_vtbl3:
03268       return SelectVTBL(N, false, 3, ARM::VTBL3Pseudo);
03269     case Intrinsic::arm_neon_vtbl4:
03270       return SelectVTBL(N, false, 4, ARM::VTBL4Pseudo);
03271 
03272     case Intrinsic::arm_neon_vtbx2:
03273       return SelectVTBL(N, true, 2, ARM::VTBX2);
03274     case Intrinsic::arm_neon_vtbx3:
03275       return SelectVTBL(N, true, 3, ARM::VTBX3Pseudo);
03276     case Intrinsic::arm_neon_vtbx4:
03277       return SelectVTBL(N, true, 4, ARM::VTBX4Pseudo);
03278     }
03279     break;
03280   }
03281 
03282   case ARMISD::VTBL1: {
03283     SDLoc dl(N);
03284     EVT VT = N->getValueType(0);
03285     SmallVector<SDValue, 6> Ops;
03286 
03287     Ops.push_back(N->getOperand(0));
03288     Ops.push_back(N->getOperand(1));
03289     Ops.push_back(getAL(CurDAG));                    // Predicate
03290     Ops.push_back(CurDAG->getRegister(0, MVT::i32)); // Predicate Register
03291     return CurDAG->getMachineNode(ARM::VTBL1, dl, VT, Ops);
03292   }
03293   case ARMISD::VTBL2: {
03294     SDLoc dl(N);
03295     EVT VT = N->getValueType(0);
03296 
03297     // Form a REG_SEQUENCE to force register allocation.
03298     SDValue V0 = N->getOperand(0);
03299     SDValue V1 = N->getOperand(1);
03300     SDValue RegSeq = SDValue(createDRegPairNode(MVT::v16i8, V0, V1), 0);
03301 
03302     SmallVector<SDValue, 6> Ops;
03303     Ops.push_back(RegSeq);
03304     Ops.push_back(N->getOperand(2));
03305     Ops.push_back(getAL(CurDAG));                    // Predicate
03306     Ops.push_back(CurDAG->getRegister(0, MVT::i32)); // Predicate Register
03307     return CurDAG->getMachineNode(ARM::VTBL2, dl, VT, Ops);
03308   }
03309 
03310   case ISD::CONCAT_VECTORS:
03311     return SelectConcatVector(N);
03312   }
03313 
03314   return SelectCode(N);
03315 }
03316 
03317 SDNode *ARMDAGToDAGISel::SelectInlineAsm(SDNode *N){
03318   std::vector<SDValue> AsmNodeOperands;
03319   unsigned Flag, Kind;
03320   bool Changed = false;
03321   unsigned NumOps = N->getNumOperands();
03322 
03323   // Normally, i64 data is bounded to two arbitrary GRPs for "%r" constraint.
03324   // However, some instrstions (e.g. ldrexd/strexd in ARM mode) require
03325   // (even/even+1) GPRs and use %n and %Hn to refer to the individual regs
03326   // respectively. Since there is no constraint to explicitly specify a
03327   // reg pair, we use GPRPair reg class for "%r" for 64-bit data. For Thumb,
03328   // the 64-bit data may be referred by H, Q, R modifiers, so we still pack
03329   // them into a GPRPair.
03330 
03331   SDLoc dl(N);
03332   SDValue Glue = N->getGluedNode() ? N->getOperand(NumOps-1)
03333                                    : SDValue(nullptr,0);
03334 
03335   SmallVector<bool, 8> OpChanged;
03336   // Glue node will be appended late.
03337   for(unsigned i = 0, e = N->getGluedNode() ? NumOps - 1 : NumOps; i < e; ++i) {
03338     SDValue op = N->getOperand(i);
03339     AsmNodeOperands.push_back(op);
03340 
03341     if (i < InlineAsm::Op_FirstOperand)
03342       continue;
03343 
03344     if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(i))) {
03345       Flag = C->getZExtValue();
03346       Kind = InlineAsm::getKind(Flag);
03347     }
03348     else
03349       continue;
03350 
03351     // Immediate operands to inline asm in the SelectionDAG are modeled with
03352     // two operands. The first is a constant of value InlineAsm::Kind_Imm, and
03353     // the second is a constant with the value of the immediate. If we get here
03354     // and we have a Kind_Imm, skip the next operand, and continue.
03355     if (Kind == InlineAsm::Kind_Imm) {
03356       SDValue op = N->getOperand(++i);
03357       AsmNodeOperands.push_back(op);
03358       continue;
03359     }
03360 
03361     unsigned NumRegs = InlineAsm::getNumOperandRegisters(Flag);
03362     if (NumRegs)
03363       OpChanged.push_back(false);
03364 
03365     unsigned DefIdx = 0;
03366     bool IsTiedToChangedOp = false;
03367     // If it's a use that is tied with a previous def, it has no
03368     // reg class constraint.
03369     if (Changed && InlineAsm::isUseOperandTiedToDef(Flag, DefIdx))
03370       IsTiedToChangedOp = OpChanged[DefIdx];
03371 
03372     if (Kind != InlineAsm::Kind_RegUse && Kind != InlineAsm::Kind_RegDef
03373         && Kind != InlineAsm::Kind_RegDefEarlyClobber)
03374       continue;
03375 
03376     unsigned RC;
03377     bool HasRC = InlineAsm::hasRegClassConstraint(Flag, RC);
03378     if ((!IsTiedToChangedOp && (!HasRC || RC != ARM::GPRRegClassID))
03379         || NumRegs != 2)
03380       continue;
03381 
03382     assert((i+2 < NumOps) && "Invalid number of operands in inline asm");
03383     SDValue V0 = N->getOperand(i+1);
03384     SDValue V1 = N->getOperand(i+2);
03385     unsigned Reg0 = cast<RegisterSDNode>(V0)->getReg();
03386     unsigned Reg1 = cast<RegisterSDNode>(V1)->getReg();
03387     SDValue PairedReg;
03388     MachineRegisterInfo &MRI = MF->getRegInfo();
03389 
03390     if (Kind == InlineAsm::Kind_RegDef ||
03391         Kind == InlineAsm::Kind_RegDefEarlyClobber) {
03392       // Replace the two GPRs with 1 GPRPair and copy values from GPRPair to
03393       // the original GPRs.
03394 
03395       unsigned GPVR = MRI.createVirtualRegister(&ARM::GPRPairRegClass);
03396       PairedReg = CurDAG->getRegister(GPVR, MVT::Untyped);
03397       SDValue Chain = SDValue(N,0);
03398 
03399       SDNode *GU = N->getGluedUser();
03400       SDValue RegCopy = CurDAG->getCopyFromReg(Chain, dl, GPVR, MVT::Untyped,
03401                                                Chain.getValue(1));
03402 
03403       // Extract values from a GPRPair reg and copy to the original GPR reg.
03404       SDValue Sub0 = CurDAG->getTargetExtractSubreg(ARM::gsub_0, dl, MVT::i32,
03405                                                     RegCopy);
03406       SDValue Sub1 = CurDAG->getTargetExtractSubreg(ARM::gsub_1, dl, MVT::i32,
03407                                                     RegCopy);
03408       SDValue T0 = CurDAG->getCopyToReg(Sub0, dl, Reg0, Sub0,
03409                                         RegCopy.getValue(1));
03410       SDValue T1 = CurDAG->getCopyToReg(Sub1, dl, Reg1, Sub1, T0.getValue(1));
03411 
03412       // Update the original glue user.
03413       std::vector<SDValue> Ops(GU->op_begin(), GU->op_end()-1);
03414       Ops.push_back(T1.getValue(1));
03415       CurDAG->UpdateNodeOperands(GU, Ops);
03416       GU = T1.getNode();
03417     }
03418     else {
03419       // For Kind  == InlineAsm::Kind_RegUse, we first copy two GPRs into a
03420       // GPRPair and then pass the GPRPair to the inline asm.
03421       SDValue Chain = AsmNodeOperands[InlineAsm::Op_InputChain];
03422 
03423       // As REG_SEQ doesn't take RegisterSDNode, we copy them first.
03424       SDValue T0 = CurDAG->getCopyFromReg(Chain, dl, Reg0, MVT::i32,
03425                                           Chain.getValue(1));
03426       SDValue T1 = CurDAG->getCopyFromReg(Chain, dl, Reg1, MVT::i32,
03427                                           T0.getValue(1));
03428       SDValue Pair = SDValue(createGPRPairNode(MVT::Untyped, T0, T1), 0);
03429 
03430       // Copy REG_SEQ into a GPRPair-typed VR and replace the original two
03431       // i32 VRs of inline asm with it.
03432       unsigned GPVR = MRI.createVirtualRegister(&ARM::GPRPairRegClass);
03433       PairedReg = CurDAG->getRegister(GPVR, MVT::Untyped);
03434       Chain = CurDAG->getCopyToReg(T1, dl, GPVR, Pair, T1.getValue(1));
03435 
03436       AsmNodeOperands[InlineAsm::Op_InputChain] = Chain;
03437       Glue = Chain.getValue(1);
03438     }
03439 
03440     Changed = true;
03441 
03442     if(PairedReg.getNode()) {
03443       OpChanged[OpChanged.size() -1 ] = true;
03444       Flag = InlineAsm::getFlagWord(Kind, 1 /* RegNum*/);
03445       if (IsTiedToChangedOp)
03446         Flag = InlineAsm::getFlagWordForMatchingOp(Flag, DefIdx);
03447       else
03448         Flag = InlineAsm::getFlagWordForRegClass(Flag, ARM::GPRPairRegClassID);
03449       // Replace the current flag.
03450       AsmNodeOperands[AsmNodeOperands.size() -1] = CurDAG->getTargetConstant(
03451           Flag, MVT::i32);
03452       // Add the new register node and skip the original two GPRs.
03453       AsmNodeOperands.push_back(PairedReg);
03454       // Skip the next two GPRs.
03455       i += 2;
03456     }
03457   }
03458 
03459   if (Glue.getNode())
03460     AsmNodeOperands.push_back(Glue);
03461   if (!Changed)
03462     return nullptr;
03463 
03464   SDValue New = CurDAG->getNode(ISD::INLINEASM, SDLoc(N),
03465       CurDAG->getVTList(MVT::Other, MVT::Glue), AsmNodeOperands);
03466   New->setNodeId(-1);
03467   return New.getNode();
03468 }
03469 
03470 
03471 bool ARMDAGToDAGISel::
03472 SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
03473                              std::vector<SDValue> &OutOps) {
03474   assert(ConstraintCode == 'm' && "unexpected asm memory constraint");
03475   // Require the address to be in a register.  That is safe for all ARM
03476   // variants and it is hard to do anything much smarter without knowing
03477   // how the operand is used.
03478   OutOps.push_back(Op);
03479   return false;
03480 }
03481 
03482 /// createARMISelDag - This pass converts a legalized DAG into a
03483 /// ARM-specific DAG, ready for instruction scheduling.
03484 ///
03485 FunctionPass *llvm::createARMISelDag(ARMBaseTargetMachine &TM,
03486                                      CodeGenOpt::Level OptLevel) {
03487   return new ARMDAGToDAGISel(TM, OptLevel);
03488 }