172062f5744557e270a38192554c3126ea5f97434Tim Northover//===-- AArch64ISelDAGToDAG.cpp - A dag to dag inst selector for AArch64 --===//
272062f5744557e270a38192554c3126ea5f97434Tim Northover//
372062f5744557e270a38192554c3126ea5f97434Tim Northover//                     The LLVM Compiler Infrastructure
472062f5744557e270a38192554c3126ea5f97434Tim Northover//
572062f5744557e270a38192554c3126ea5f97434Tim Northover// This file is distributed under the University of Illinois Open Source
672062f5744557e270a38192554c3126ea5f97434Tim Northover// License. See LICENSE.TXT for details.
772062f5744557e270a38192554c3126ea5f97434Tim Northover//
872062f5744557e270a38192554c3126ea5f97434Tim Northover//===----------------------------------------------------------------------===//
972062f5744557e270a38192554c3126ea5f97434Tim Northover//
1072062f5744557e270a38192554c3126ea5f97434Tim Northover// This file defines an instruction selector for the AArch64 target.
1172062f5744557e270a38192554c3126ea5f97434Tim Northover//
1272062f5744557e270a38192554c3126ea5f97434Tim Northover//===----------------------------------------------------------------------===//
1372062f5744557e270a38192554c3126ea5f97434Tim Northover
1472062f5744557e270a38192554c3126ea5f97434Tim Northover#define DEBUG_TYPE "aarch64-isel"
1572062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64.h"
1672062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64InstrInfo.h"
1772062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64Subtarget.h"
1872062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64TargetMachine.h"
1919254c49a8752fe8c6fa648a6eb29f20a1f62c8bTim Northover#include "Utils/AArch64BaseInfo.h"
2072062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/ADT/APSInt.h"
2172062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/CodeGen/SelectionDAGISel.h"
2272062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/IR/GlobalValue.h"
2372062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/Support/Debug.h"
2472062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/Support/raw_ostream.h"
2572062f5744557e270a38192554c3126ea5f97434Tim Northover
2672062f5744557e270a38192554c3126ea5f97434Tim Northoverusing namespace llvm;
2772062f5744557e270a38192554c3126ea5f97434Tim Northover
2872062f5744557e270a38192554c3126ea5f97434Tim Northover//===--------------------------------------------------------------------===//
2972062f5744557e270a38192554c3126ea5f97434Tim Northover/// AArch64 specific code to select AArch64 machine instructions for
3072062f5744557e270a38192554c3126ea5f97434Tim Northover/// SelectionDAG operations.
3172062f5744557e270a38192554c3126ea5f97434Tim Northover///
3272062f5744557e270a38192554c3126ea5f97434Tim Northovernamespace {
3372062f5744557e270a38192554c3126ea5f97434Tim Northover
3472062f5744557e270a38192554c3126ea5f97434Tim Northoverclass AArch64DAGToDAGISel : public SelectionDAGISel {
3572062f5744557e270a38192554c3126ea5f97434Tim Northover  AArch64TargetMachine &TM;
3672062f5744557e270a38192554c3126ea5f97434Tim Northover  const AArch64InstrInfo *TII;
3772062f5744557e270a38192554c3126ea5f97434Tim Northover
3872062f5744557e270a38192554c3126ea5f97434Tim Northover  /// Keep a pointer to the AArch64Subtarget around so that we can
3972062f5744557e270a38192554c3126ea5f97434Tim Northover  /// make the right decision when generating code for different targets.
4072062f5744557e270a38192554c3126ea5f97434Tim Northover  const AArch64Subtarget *Subtarget;
4172062f5744557e270a38192554c3126ea5f97434Tim Northover
4272062f5744557e270a38192554c3126ea5f97434Tim Northoverpublic:
4372062f5744557e270a38192554c3126ea5f97434Tim Northover  explicit AArch64DAGToDAGISel(AArch64TargetMachine &tm,
4472062f5744557e270a38192554c3126ea5f97434Tim Northover                               CodeGenOpt::Level OptLevel)
4572062f5744557e270a38192554c3126ea5f97434Tim Northover    : SelectionDAGISel(tm, OptLevel), TM(tm),
4672062f5744557e270a38192554c3126ea5f97434Tim Northover      TII(static_cast<const AArch64InstrInfo*>(TM.getInstrInfo())),
4772062f5744557e270a38192554c3126ea5f97434Tim Northover      Subtarget(&TM.getSubtarget<AArch64Subtarget>()) {
4872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
4972062f5744557e270a38192554c3126ea5f97434Tim Northover
5072062f5744557e270a38192554c3126ea5f97434Tim Northover  virtual const char *getPassName() const {
5172062f5744557e270a38192554c3126ea5f97434Tim Northover    return "AArch64 Instruction Selection";
5272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
5372062f5744557e270a38192554c3126ea5f97434Tim Northover
5472062f5744557e270a38192554c3126ea5f97434Tim Northover  // Include the pieces autogenerated from the target description.
5572062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64GenDAGISel.inc"
5672062f5744557e270a38192554c3126ea5f97434Tim Northover
5772062f5744557e270a38192554c3126ea5f97434Tim Northover  template<unsigned MemSize>
5872062f5744557e270a38192554c3126ea5f97434Tim Northover  bool SelectOffsetUImm12(SDValue N, SDValue &UImm12) {
5972062f5744557e270a38192554c3126ea5f97434Tim Northover    const ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N);
6072062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!CN || CN->getZExtValue() % MemSize != 0
6172062f5744557e270a38192554c3126ea5f97434Tim Northover        || CN->getZExtValue() / MemSize > 0xfff)
6272062f5744557e270a38192554c3126ea5f97434Tim Northover      return false;
6372062f5744557e270a38192554c3126ea5f97434Tim Northover
6472062f5744557e270a38192554c3126ea5f97434Tim Northover    UImm12 =  CurDAG->getTargetConstant(CN->getZExtValue() / MemSize, MVT::i64);
6572062f5744557e270a38192554c3126ea5f97434Tim Northover    return true;
6672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
6772062f5744557e270a38192554c3126ea5f97434Tim Northover
6872062f5744557e270a38192554c3126ea5f97434Tim Northover  template<unsigned RegWidth>
6972062f5744557e270a38192554c3126ea5f97434Tim Northover  bool SelectCVTFixedPosOperand(SDValue N, SDValue &FixedPos) {
7072062f5744557e270a38192554c3126ea5f97434Tim Northover    return SelectCVTFixedPosOperand(N, FixedPos, RegWidth);
7172062f5744557e270a38192554c3126ea5f97434Tim Northover  }
7272062f5744557e270a38192554c3126ea5f97434Tim Northover
7372062f5744557e270a38192554c3126ea5f97434Tim Northover  bool SelectFPZeroOperand(SDValue N, SDValue &Dummy);
7472062f5744557e270a38192554c3126ea5f97434Tim Northover
75dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover  bool SelectCVTFixedPosOperand(SDValue N, SDValue &FixedPos,
76dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover                                unsigned RegWidth);
7772062f5744557e270a38192554c3126ea5f97434Tim Northover
7872062f5744557e270a38192554c3126ea5f97434Tim Northover  bool SelectInlineAsmMemoryOperand(const SDValue &Op,
7972062f5744557e270a38192554c3126ea5f97434Tim Northover                                    char ConstraintCode,
8072062f5744557e270a38192554c3126ea5f97434Tim Northover                                    std::vector<SDValue> &OutOps);
8172062f5744557e270a38192554c3126ea5f97434Tim Northover
8272062f5744557e270a38192554c3126ea5f97434Tim Northover  bool SelectLogicalImm(SDValue N, SDValue &Imm);
8372062f5744557e270a38192554c3126ea5f97434Tim Northover
8472062f5744557e270a38192554c3126ea5f97434Tim Northover  template<unsigned RegWidth>
8572062f5744557e270a38192554c3126ea5f97434Tim Northover  bool SelectTSTBOperand(SDValue N, SDValue &FixedPos) {
8672062f5744557e270a38192554c3126ea5f97434Tim Northover    return SelectTSTBOperand(N, FixedPos, RegWidth);
8772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
8872062f5744557e270a38192554c3126ea5f97434Tim Northover
8972062f5744557e270a38192554c3126ea5f97434Tim Northover  bool SelectTSTBOperand(SDValue N, SDValue &FixedPos, unsigned RegWidth);
9072062f5744557e270a38192554c3126ea5f97434Tim Northover
9172062f5744557e270a38192554c3126ea5f97434Tim Northover  SDNode *TrySelectToMoveImm(SDNode *N);
921e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover  SDNode *LowerToFPLitPool(SDNode *Node);
9372062f5744557e270a38192554c3126ea5f97434Tim Northover  SDNode *SelectToLitPool(SDNode *N);
9472062f5744557e270a38192554c3126ea5f97434Tim Northover
9572062f5744557e270a38192554c3126ea5f97434Tim Northover  SDNode* Select(SDNode*);
9672062f5744557e270a38192554c3126ea5f97434Tim Northoverprivate:
9772062f5744557e270a38192554c3126ea5f97434Tim Northover};
9872062f5744557e270a38192554c3126ea5f97434Tim Northover}
9972062f5744557e270a38192554c3126ea5f97434Tim Northover
10072062f5744557e270a38192554c3126ea5f97434Tim Northoverbool
10172062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64DAGToDAGISel::SelectCVTFixedPosOperand(SDValue N, SDValue &FixedPos,
10272062f5744557e270a38192554c3126ea5f97434Tim Northover                                              unsigned RegWidth) {
10372062f5744557e270a38192554c3126ea5f97434Tim Northover  const ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
10472062f5744557e270a38192554c3126ea5f97434Tim Northover  if (!CN) return false;
10572062f5744557e270a38192554c3126ea5f97434Tim Northover
10672062f5744557e270a38192554c3126ea5f97434Tim Northover  // An FCVT[SU] instruction performs: convertToInt(Val * 2^fbits) where fbits
10772062f5744557e270a38192554c3126ea5f97434Tim Northover  // is between 1 and 32 for a destination w-register, or 1 and 64 for an
10872062f5744557e270a38192554c3126ea5f97434Tim Northover  // x-register.
10972062f5744557e270a38192554c3126ea5f97434Tim Northover  //
11072062f5744557e270a38192554c3126ea5f97434Tim Northover  // By this stage, we've detected (fp_to_[su]int (fmul Val, THIS_NODE)) so we
11172062f5744557e270a38192554c3126ea5f97434Tim Northover  // want THIS_NODE to be 2^fbits. This is much easier to deal with using
11272062f5744557e270a38192554c3126ea5f97434Tim Northover  // integers.
11372062f5744557e270a38192554c3126ea5f97434Tim Northover  bool IsExact;
11472062f5744557e270a38192554c3126ea5f97434Tim Northover
11572062f5744557e270a38192554c3126ea5f97434Tim Northover  // fbits is between 1 and 64 in the worst-case, which means the fmul
11672062f5744557e270a38192554c3126ea5f97434Tim Northover  // could have 2^64 as an actual operand. Need 65 bits of precision.
11772062f5744557e270a38192554c3126ea5f97434Tim Northover  APSInt IntVal(65, true);
11872062f5744557e270a38192554c3126ea5f97434Tim Northover  CN->getValueAPF().convertToInteger(IntVal, APFloat::rmTowardZero, &IsExact);
11972062f5744557e270a38192554c3126ea5f97434Tim Northover
12072062f5744557e270a38192554c3126ea5f97434Tim Northover  // N.b. isPowerOf2 also checks for > 0.
12172062f5744557e270a38192554c3126ea5f97434Tim Northover  if (!IsExact || !IntVal.isPowerOf2()) return false;
12272062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned FBits = IntVal.logBase2();
12372062f5744557e270a38192554c3126ea5f97434Tim Northover
12472062f5744557e270a38192554c3126ea5f97434Tim Northover  // Checks above should have guaranteed that we haven't lost information in
12572062f5744557e270a38192554c3126ea5f97434Tim Northover  // finding FBits, but it must still be in range.
12672062f5744557e270a38192554c3126ea5f97434Tim Northover  if (FBits == 0 || FBits > RegWidth) return false;
12772062f5744557e270a38192554c3126ea5f97434Tim Northover
12872062f5744557e270a38192554c3126ea5f97434Tim Northover  FixedPos = CurDAG->getTargetConstant(64 - FBits, MVT::i32);
12972062f5744557e270a38192554c3126ea5f97434Tim Northover  return true;
13072062f5744557e270a38192554c3126ea5f97434Tim Northover}
13172062f5744557e270a38192554c3126ea5f97434Tim Northover
13272062f5744557e270a38192554c3126ea5f97434Tim Northoverbool
13372062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64DAGToDAGISel::SelectInlineAsmMemoryOperand(const SDValue &Op,
134dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover                                                 char ConstraintCode,
135dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover                                                 std::vector<SDValue> &OutOps) {
13672062f5744557e270a38192554c3126ea5f97434Tim Northover  switch (ConstraintCode) {
13772062f5744557e270a38192554c3126ea5f97434Tim Northover  default: llvm_unreachable("Unrecognised AArch64 memory constraint");
13872062f5744557e270a38192554c3126ea5f97434Tim Northover  case 'm':
13972062f5744557e270a38192554c3126ea5f97434Tim Northover    // FIXME: more freedom is actually permitted for 'm'. We can go
14072062f5744557e270a38192554c3126ea5f97434Tim Northover    // hunting for a base and an offset if we want. Of course, since
14172062f5744557e270a38192554c3126ea5f97434Tim Northover    // we don't really know how the operand is going to be used we're
14272062f5744557e270a38192554c3126ea5f97434Tim Northover    // probably restricted to the load/store pair's simm7 as an offset
14372062f5744557e270a38192554c3126ea5f97434Tim Northover    // range anyway.
14472062f5744557e270a38192554c3126ea5f97434Tim Northover  case 'Q':
14572062f5744557e270a38192554c3126ea5f97434Tim Northover    OutOps.push_back(Op);
14672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
14772062f5744557e270a38192554c3126ea5f97434Tim Northover
14872062f5744557e270a38192554c3126ea5f97434Tim Northover  return false;
14972062f5744557e270a38192554c3126ea5f97434Tim Northover}
15072062f5744557e270a38192554c3126ea5f97434Tim Northover
15172062f5744557e270a38192554c3126ea5f97434Tim Northoverbool
15272062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64DAGToDAGISel::SelectFPZeroOperand(SDValue N, SDValue &Dummy) {
15372062f5744557e270a38192554c3126ea5f97434Tim Northover  ConstantFPSDNode *Imm = dyn_cast<ConstantFPSDNode>(N);
15472062f5744557e270a38192554c3126ea5f97434Tim Northover  if (!Imm || !Imm->getValueAPF().isPosZero())
15572062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
156dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover
15772062f5744557e270a38192554c3126ea5f97434Tim Northover  // Doesn't actually carry any information, but keeps TableGen quiet.
15872062f5744557e270a38192554c3126ea5f97434Tim Northover  Dummy = CurDAG->getTargetConstant(0, MVT::i32);
15972062f5744557e270a38192554c3126ea5f97434Tim Northover  return true;
16072062f5744557e270a38192554c3126ea5f97434Tim Northover}
16172062f5744557e270a38192554c3126ea5f97434Tim Northover
16272062f5744557e270a38192554c3126ea5f97434Tim Northoverbool AArch64DAGToDAGISel::SelectLogicalImm(SDValue N, SDValue &Imm) {
16372062f5744557e270a38192554c3126ea5f97434Tim Northover  uint32_t Bits;
16472062f5744557e270a38192554c3126ea5f97434Tim Northover  uint32_t RegWidth = N.getValueType().getSizeInBits();
16572062f5744557e270a38192554c3126ea5f97434Tim Northover
16672062f5744557e270a38192554c3126ea5f97434Tim Northover  ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N);
16772062f5744557e270a38192554c3126ea5f97434Tim Northover  if (!CN) return false;
16872062f5744557e270a38192554c3126ea5f97434Tim Northover
16972062f5744557e270a38192554c3126ea5f97434Tim Northover  if (!A64Imms::isLogicalImm(RegWidth, CN->getZExtValue(), Bits))
17072062f5744557e270a38192554c3126ea5f97434Tim Northover    return false;
17172062f5744557e270a38192554c3126ea5f97434Tim Northover
17272062f5744557e270a38192554c3126ea5f97434Tim Northover  Imm = CurDAG->getTargetConstant(Bits, MVT::i32);
17372062f5744557e270a38192554c3126ea5f97434Tim Northover  return true;
17472062f5744557e270a38192554c3126ea5f97434Tim Northover}
17572062f5744557e270a38192554c3126ea5f97434Tim Northover
17672062f5744557e270a38192554c3126ea5f97434Tim NorthoverSDNode *AArch64DAGToDAGISel::TrySelectToMoveImm(SDNode *Node) {
17772062f5744557e270a38192554c3126ea5f97434Tim Northover  SDNode *ResNode;
17872062f5744557e270a38192554c3126ea5f97434Tim Northover  DebugLoc dl = Node->getDebugLoc();
17972062f5744557e270a38192554c3126ea5f97434Tim Northover  EVT DestType = Node->getValueType(0);
18072062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned DestWidth = DestType.getSizeInBits();
18172062f5744557e270a38192554c3126ea5f97434Tim Northover
18272062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned MOVOpcode;
18372062f5744557e270a38192554c3126ea5f97434Tim Northover  EVT MOVType;
18472062f5744557e270a38192554c3126ea5f97434Tim Northover  int UImm16, Shift;
18572062f5744557e270a38192554c3126ea5f97434Tim Northover  uint32_t LogicalBits;
18672062f5744557e270a38192554c3126ea5f97434Tim Northover
18772062f5744557e270a38192554c3126ea5f97434Tim Northover  uint64_t BitPat = cast<ConstantSDNode>(Node)->getZExtValue();
18872062f5744557e270a38192554c3126ea5f97434Tim Northover  if (A64Imms::isMOVZImm(DestWidth, BitPat, UImm16, Shift)) {
18972062f5744557e270a38192554c3126ea5f97434Tim Northover    MOVType = DestType;
19072062f5744557e270a38192554c3126ea5f97434Tim Northover    MOVOpcode = DestWidth == 64 ? AArch64::MOVZxii : AArch64::MOVZwii;
19172062f5744557e270a38192554c3126ea5f97434Tim Northover  } else if (A64Imms::isMOVNImm(DestWidth, BitPat, UImm16, Shift)) {
19272062f5744557e270a38192554c3126ea5f97434Tim Northover    MOVType = DestType;
19372062f5744557e270a38192554c3126ea5f97434Tim Northover    MOVOpcode = DestWidth == 64 ? AArch64::MOVNxii : AArch64::MOVNwii;
19472062f5744557e270a38192554c3126ea5f97434Tim Northover  } else if (DestWidth == 64 && A64Imms::isMOVNImm(32, BitPat, UImm16, Shift)) {
19572062f5744557e270a38192554c3126ea5f97434Tim Northover    // To get something like 0x0000_0000_ffff_1234 into a 64-bit register we can
19672062f5744557e270a38192554c3126ea5f97434Tim Northover    // use a 32-bit instruction: "movn w0, 0xedbc".
19772062f5744557e270a38192554c3126ea5f97434Tim Northover    MOVType = MVT::i32;
19872062f5744557e270a38192554c3126ea5f97434Tim Northover    MOVOpcode = AArch64::MOVNwii;
19972062f5744557e270a38192554c3126ea5f97434Tim Northover  } else if (A64Imms::isLogicalImm(DestWidth, BitPat, LogicalBits))  {
20072062f5744557e270a38192554c3126ea5f97434Tim Northover    MOVOpcode = DestWidth == 64 ? AArch64::ORRxxi : AArch64::ORRwwi;
20172062f5744557e270a38192554c3126ea5f97434Tim Northover    uint16_t ZR = DestWidth == 64 ? AArch64::XZR : AArch64::WZR;
20272062f5744557e270a38192554c3126ea5f97434Tim Northover
20372062f5744557e270a38192554c3126ea5f97434Tim Northover    return CurDAG->getMachineNode(MOVOpcode, dl, DestType,
20472062f5744557e270a38192554c3126ea5f97434Tim Northover                              CurDAG->getRegister(ZR, DestType),
20572062f5744557e270a38192554c3126ea5f97434Tim Northover                              CurDAG->getTargetConstant(LogicalBits, MVT::i32));
20672062f5744557e270a38192554c3126ea5f97434Tim Northover  } else {
20772062f5744557e270a38192554c3126ea5f97434Tim Northover    // Can't handle it in one instruction. There's scope for permitting two (or
20872062f5744557e270a38192554c3126ea5f97434Tim Northover    // more) instructions, but that'll need more thought.
20972062f5744557e270a38192554c3126ea5f97434Tim Northover    return NULL;
21072062f5744557e270a38192554c3126ea5f97434Tim Northover  }
21172062f5744557e270a38192554c3126ea5f97434Tim Northover
21272062f5744557e270a38192554c3126ea5f97434Tim Northover  ResNode = CurDAG->getMachineNode(MOVOpcode, dl, MOVType,
21372062f5744557e270a38192554c3126ea5f97434Tim Northover                                   CurDAG->getTargetConstant(UImm16, MVT::i32),
21472062f5744557e270a38192554c3126ea5f97434Tim Northover                                   CurDAG->getTargetConstant(Shift, MVT::i32));
21572062f5744557e270a38192554c3126ea5f97434Tim Northover
21672062f5744557e270a38192554c3126ea5f97434Tim Northover  if (MOVType != DestType) {
21772062f5744557e270a38192554c3126ea5f97434Tim Northover    ResNode = CurDAG->getMachineNode(TargetOpcode::SUBREG_TO_REG, dl,
21872062f5744557e270a38192554c3126ea5f97434Tim Northover                          MVT::i64, MVT::i32, MVT::Other,
21972062f5744557e270a38192554c3126ea5f97434Tim Northover                          CurDAG->getTargetConstant(0, MVT::i64),
22072062f5744557e270a38192554c3126ea5f97434Tim Northover                          SDValue(ResNode, 0),
22172062f5744557e270a38192554c3126ea5f97434Tim Northover                          CurDAG->getTargetConstant(AArch64::sub_32, MVT::i32));
22272062f5744557e270a38192554c3126ea5f97434Tim Northover  }
22372062f5744557e270a38192554c3126ea5f97434Tim Northover
22472062f5744557e270a38192554c3126ea5f97434Tim Northover  return ResNode;
22572062f5744557e270a38192554c3126ea5f97434Tim Northover}
22672062f5744557e270a38192554c3126ea5f97434Tim Northover
22772062f5744557e270a38192554c3126ea5f97434Tim NorthoverSDNode *AArch64DAGToDAGISel::SelectToLitPool(SDNode *Node) {
2281e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover  DebugLoc DL = Node->getDebugLoc();
22972062f5744557e270a38192554c3126ea5f97434Tim Northover  uint64_t UnsignedVal = cast<ConstantSDNode>(Node)->getZExtValue();
23072062f5744557e270a38192554c3126ea5f97434Tim Northover  int64_t SignedVal = cast<ConstantSDNode>(Node)->getSExtValue();
23172062f5744557e270a38192554c3126ea5f97434Tim Northover  EVT DestType = Node->getValueType(0);
2321e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover  EVT PtrVT = TLI.getPointerTy();
23372062f5744557e270a38192554c3126ea5f97434Tim Northover
23472062f5744557e270a38192554c3126ea5f97434Tim Northover  // Since we may end up loading a 64-bit constant from a 32-bit entry the
23572062f5744557e270a38192554c3126ea5f97434Tim Northover  // constant in the pool may have a different type to the eventual node.
2361e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover  ISD::LoadExtType Extension;
2371e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover  EVT MemType;
23872062f5744557e270a38192554c3126ea5f97434Tim Northover
23972062f5744557e270a38192554c3126ea5f97434Tim Northover  assert((DestType == MVT::i64 || DestType == MVT::i32)
24072062f5744557e270a38192554c3126ea5f97434Tim Northover         && "Only expect integer constants at the moment");
24172062f5744557e270a38192554c3126ea5f97434Tim Northover
2421e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover  if (DestType == MVT::i32) {
2431e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover    Extension = ISD::NON_EXTLOAD;
2441e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover    MemType = MVT::i32;
2451e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover  } else if (UnsignedVal <= UINT32_MAX) {
2461e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover    Extension = ISD::ZEXTLOAD;
2471e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover    MemType = MVT::i32;
24872062f5744557e270a38192554c3126ea5f97434Tim Northover  } else if (SignedVal >= INT32_MIN && SignedVal <= INT32_MAX) {
2491e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover    Extension = ISD::SEXTLOAD;
2501e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover    MemType = MVT::i32;
25172062f5744557e270a38192554c3126ea5f97434Tim Northover  } else {
2521e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover    Extension = ISD::NON_EXTLOAD;
2531e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover    MemType = MVT::i64;
25472062f5744557e270a38192554c3126ea5f97434Tim Northover  }
25572062f5744557e270a38192554c3126ea5f97434Tim Northover
2561e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover  Constant *CV = ConstantInt::get(Type::getIntNTy(*CurDAG->getContext(),
2571e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover                                                  MemType.getSizeInBits()),
2581e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover                                  UnsignedVal);
2591e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover  SDValue PoolAddr;
2601e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover  unsigned Alignment = TLI.getDataLayout()->getABITypeAlignment(CV->getType());
2611e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover  PoolAddr = CurDAG->getNode(AArch64ISD::WrapperSmall, DL, PtrVT,
2621e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover                             CurDAG->getTargetConstantPool(CV, PtrVT, 0, 0,
2631e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover                                                         AArch64II::MO_NO_FLAG),
2641e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover                             CurDAG->getTargetConstantPool(CV, PtrVT, 0, 0,
2651e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover                                                           AArch64II::MO_LO12),
2661e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover                             CurDAG->getConstant(Alignment, MVT::i32));
2671e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover
2681e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover  return CurDAG->getExtLoad(Extension, DL, DestType, CurDAG->getEntryNode(),
2691e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover                            PoolAddr,
2701e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover                            MachinePointerInfo::getConstantPool(), MemType,
2711e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover                            /* isVolatile = */ false,
2721e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover                            /* isNonTemporal = */ false,
2731e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover                            Alignment).getNode();
27472062f5744557e270a38192554c3126ea5f97434Tim Northover}
27572062f5744557e270a38192554c3126ea5f97434Tim Northover
2761e8839302b70d77de63844332bdee9ce7d06f2c9Tim NorthoverSDNode *AArch64DAGToDAGISel::LowerToFPLitPool(SDNode *Node) {
2771e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover  DebugLoc DL = Node->getDebugLoc();
27872062f5744557e270a38192554c3126ea5f97434Tim Northover  const ConstantFP *FV = cast<ConstantFPSDNode>(Node)->getConstantFPValue();
2791e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover  EVT PtrVT = TLI.getPointerTy();
28072062f5744557e270a38192554c3126ea5f97434Tim Northover  EVT DestType = Node->getValueType(0);
28172062f5744557e270a38192554c3126ea5f97434Tim Northover
2821e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover  unsigned Alignment = TLI.getDataLayout()->getABITypeAlignment(FV->getType());
2831e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover  SDValue PoolAddr;
2841e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover
2851e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover  assert(TM.getCodeModel() == CodeModel::Small &&
2861e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover         "Only small code model supported");
2871e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover  PoolAddr = CurDAG->getNode(AArch64ISD::WrapperSmall, DL, PtrVT,
2881e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover                             CurDAG->getTargetConstantPool(FV, PtrVT, 0, 0,
2891e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover                                                         AArch64II::MO_NO_FLAG),
2901e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover                             CurDAG->getTargetConstantPool(FV, PtrVT, 0, 0,
2911e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover                                                           AArch64II::MO_LO12),
2921e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover                             CurDAG->getConstant(Alignment, MVT::i32));
2931e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover
2941e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover  return CurDAG->getLoad(DestType, DL, CurDAG->getEntryNode(), PoolAddr,
2951e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover                         MachinePointerInfo::getConstantPool(),
2961e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover                         /* isVolatile = */ false,
2971e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover                         /* isNonTemporal = */ false,
2981e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover                         /* isInvariant = */ true,
2991e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover                         Alignment).getNode();
30072062f5744557e270a38192554c3126ea5f97434Tim Northover}
30172062f5744557e270a38192554c3126ea5f97434Tim Northover
30272062f5744557e270a38192554c3126ea5f97434Tim Northoverbool
30372062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64DAGToDAGISel::SelectTSTBOperand(SDValue N, SDValue &FixedPos,
30472062f5744557e270a38192554c3126ea5f97434Tim Northover                                       unsigned RegWidth) {
30572062f5744557e270a38192554c3126ea5f97434Tim Northover  const ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N);
30672062f5744557e270a38192554c3126ea5f97434Tim Northover  if (!CN) return false;
30772062f5744557e270a38192554c3126ea5f97434Tim Northover
30872062f5744557e270a38192554c3126ea5f97434Tim Northover  uint64_t Val = CN->getZExtValue();
30972062f5744557e270a38192554c3126ea5f97434Tim Northover
31072062f5744557e270a38192554c3126ea5f97434Tim Northover  if (!isPowerOf2_64(Val)) return false;
31172062f5744557e270a38192554c3126ea5f97434Tim Northover
31272062f5744557e270a38192554c3126ea5f97434Tim Northover  unsigned TestedBit = Log2_64(Val);
31372062f5744557e270a38192554c3126ea5f97434Tim Northover  // Checks above should have guaranteed that we haven't lost information in
31472062f5744557e270a38192554c3126ea5f97434Tim Northover  // finding TestedBit, but it must still be in range.
31572062f5744557e270a38192554c3126ea5f97434Tim Northover  if (TestedBit >= RegWidth) return false;
31672062f5744557e270a38192554c3126ea5f97434Tim Northover
31772062f5744557e270a38192554c3126ea5f97434Tim Northover  FixedPos = CurDAG->getTargetConstant(TestedBit, MVT::i64);
31872062f5744557e270a38192554c3126ea5f97434Tim Northover  return true;
31972062f5744557e270a38192554c3126ea5f97434Tim Northover}
32072062f5744557e270a38192554c3126ea5f97434Tim Northover
32172062f5744557e270a38192554c3126ea5f97434Tim NorthoverSDNode *AArch64DAGToDAGISel::Select(SDNode *Node) {
32272062f5744557e270a38192554c3126ea5f97434Tim Northover  // Dump information about the Node being selected
32372062f5744557e270a38192554c3126ea5f97434Tim Northover  DEBUG(dbgs() << "Selecting: "; Node->dump(CurDAG); dbgs() << "\n");
32472062f5744557e270a38192554c3126ea5f97434Tim Northover
32572062f5744557e270a38192554c3126ea5f97434Tim Northover  if (Node->isMachineOpcode()) {
32672062f5744557e270a38192554c3126ea5f97434Tim Northover    DEBUG(dbgs() << "== "; Node->dump(CurDAG); dbgs() << "\n");
32772062f5744557e270a38192554c3126ea5f97434Tim Northover    return NULL;
32872062f5744557e270a38192554c3126ea5f97434Tim Northover  }
32972062f5744557e270a38192554c3126ea5f97434Tim Northover
33072062f5744557e270a38192554c3126ea5f97434Tim Northover  switch (Node->getOpcode()) {
33172062f5744557e270a38192554c3126ea5f97434Tim Northover  case ISD::FrameIndex: {
33272062f5744557e270a38192554c3126ea5f97434Tim Northover    int FI = cast<FrameIndexSDNode>(Node)->getIndex();
33372062f5744557e270a38192554c3126ea5f97434Tim Northover    EVT PtrTy = TLI.getPointerTy();
33472062f5744557e270a38192554c3126ea5f97434Tim Northover    SDValue TFI = CurDAG->getTargetFrameIndex(FI, PtrTy);
33572062f5744557e270a38192554c3126ea5f97434Tim Northover    return CurDAG->SelectNodeTo(Node, AArch64::ADDxxi_lsl0_s, PtrTy,
33672062f5744557e270a38192554c3126ea5f97434Tim Northover                                TFI, CurDAG->getTargetConstant(0, PtrTy));
33772062f5744557e270a38192554c3126ea5f97434Tim Northover  }
33872062f5744557e270a38192554c3126ea5f97434Tim Northover  case ISD::ConstantPool: {
33972062f5744557e270a38192554c3126ea5f97434Tim Northover    // Constant pools are fine, just create a Target entry.
34072062f5744557e270a38192554c3126ea5f97434Tim Northover    ConstantPoolSDNode *CN = cast<ConstantPoolSDNode>(Node);
34172062f5744557e270a38192554c3126ea5f97434Tim Northover    const Constant *C = CN->getConstVal();
34272062f5744557e270a38192554c3126ea5f97434Tim Northover    SDValue CP = CurDAG->getTargetConstantPool(C, CN->getValueType(0));
34372062f5744557e270a38192554c3126ea5f97434Tim Northover
34472062f5744557e270a38192554c3126ea5f97434Tim Northover    ReplaceUses(SDValue(Node, 0), CP);
34572062f5744557e270a38192554c3126ea5f97434Tim Northover    return NULL;
34672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
34772062f5744557e270a38192554c3126ea5f97434Tim Northover  case ISD::Constant: {
34872062f5744557e270a38192554c3126ea5f97434Tim Northover    SDNode *ResNode = 0;
34972062f5744557e270a38192554c3126ea5f97434Tim Northover    if (cast<ConstantSDNode>(Node)->getZExtValue() == 0) {
35072062f5744557e270a38192554c3126ea5f97434Tim Northover      // XZR and WZR are probably even better than an actual move: most of the
35172062f5744557e270a38192554c3126ea5f97434Tim Northover      // time they can be folded into another instruction with *no* cost.
35272062f5744557e270a38192554c3126ea5f97434Tim Northover
35372062f5744557e270a38192554c3126ea5f97434Tim Northover      EVT Ty = Node->getValueType(0);
35472062f5744557e270a38192554c3126ea5f97434Tim Northover      assert((Ty == MVT::i32 || Ty == MVT::i64) && "unexpected type");
35572062f5744557e270a38192554c3126ea5f97434Tim Northover      uint16_t Register = Ty == MVT::i32 ? AArch64::WZR : AArch64::XZR;
35672062f5744557e270a38192554c3126ea5f97434Tim Northover      ResNode = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
35772062f5744557e270a38192554c3126ea5f97434Tim Northover                                       Node->getDebugLoc(),
35872062f5744557e270a38192554c3126ea5f97434Tim Northover                                       Register, Ty).getNode();
35972062f5744557e270a38192554c3126ea5f97434Tim Northover    }
36072062f5744557e270a38192554c3126ea5f97434Tim Northover
36172062f5744557e270a38192554c3126ea5f97434Tim Northover    // Next best option is a move-immediate, see if we can do that.
36272062f5744557e270a38192554c3126ea5f97434Tim Northover    if (!ResNode) {
36372062f5744557e270a38192554c3126ea5f97434Tim Northover      ResNode = TrySelectToMoveImm(Node);
36472062f5744557e270a38192554c3126ea5f97434Tim Northover    }
36572062f5744557e270a38192554c3126ea5f97434Tim Northover
3661e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover    if (ResNode)
3671e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover      return ResNode;
36872062f5744557e270a38192554c3126ea5f97434Tim Northover
3691e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover    // If even that fails we fall back to a lit-pool entry at the moment. Future
3701e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover    // tuning may change this to a sequence of MOVZ/MOVN/MOVK instructions.
3711e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover    ResNode = SelectToLitPool(Node);
37272062f5744557e270a38192554c3126ea5f97434Tim Northover    assert(ResNode && "We need *some* way to materialise a constant");
37372062f5744557e270a38192554c3126ea5f97434Tim Northover
3741e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover    // We want to continue selection at this point since the litpool access
3751e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover    // generated used generic nodes for simplicity.
37672062f5744557e270a38192554c3126ea5f97434Tim Northover    ReplaceUses(SDValue(Node, 0), SDValue(ResNode, 0));
3771e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover    Node = ResNode;
3781e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover    break;
37972062f5744557e270a38192554c3126ea5f97434Tim Northover  }
38072062f5744557e270a38192554c3126ea5f97434Tim Northover  case ISD::ConstantFP: {
38172062f5744557e270a38192554c3126ea5f97434Tim Northover    if (A64Imms::isFPImm(cast<ConstantFPSDNode>(Node)->getValueAPF())) {
38272062f5744557e270a38192554c3126ea5f97434Tim Northover      // FMOV will take care of it from TableGen
38372062f5744557e270a38192554c3126ea5f97434Tim Northover      break;
38472062f5744557e270a38192554c3126ea5f97434Tim Northover    }
38572062f5744557e270a38192554c3126ea5f97434Tim Northover
3861e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover    SDNode *ResNode = LowerToFPLitPool(Node);
38772062f5744557e270a38192554c3126ea5f97434Tim Northover    ReplaceUses(SDValue(Node, 0), SDValue(ResNode, 0));
3881e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover
3891e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover    // We want to continue selection at this point since the litpool access
3901e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover    // generated used generic nodes for simplicity.
3911e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover    Node = ResNode;
3921e8839302b70d77de63844332bdee9ce7d06f2c9Tim Northover    break;
39372062f5744557e270a38192554c3126ea5f97434Tim Northover  }
39472062f5744557e270a38192554c3126ea5f97434Tim Northover  default:
39572062f5744557e270a38192554c3126ea5f97434Tim Northover    break; // Let generic code handle it
39672062f5744557e270a38192554c3126ea5f97434Tim Northover  }
39772062f5744557e270a38192554c3126ea5f97434Tim Northover
39872062f5744557e270a38192554c3126ea5f97434Tim Northover  SDNode *ResNode = SelectCode(Node);
39972062f5744557e270a38192554c3126ea5f97434Tim Northover
40072062f5744557e270a38192554c3126ea5f97434Tim Northover  DEBUG(dbgs() << "=> ";
40172062f5744557e270a38192554c3126ea5f97434Tim Northover        if (ResNode == NULL || ResNode == Node)
40272062f5744557e270a38192554c3126ea5f97434Tim Northover          Node->dump(CurDAG);
40372062f5744557e270a38192554c3126ea5f97434Tim Northover        else
40472062f5744557e270a38192554c3126ea5f97434Tim Northover          ResNode->dump(CurDAG);
40572062f5744557e270a38192554c3126ea5f97434Tim Northover        dbgs() << "\n");
40672062f5744557e270a38192554c3126ea5f97434Tim Northover
40772062f5744557e270a38192554c3126ea5f97434Tim Northover  return ResNode;
40872062f5744557e270a38192554c3126ea5f97434Tim Northover}
40972062f5744557e270a38192554c3126ea5f97434Tim Northover
41072062f5744557e270a38192554c3126ea5f97434Tim Northover/// This pass converts a legalized DAG into a AArch64-specific DAG, ready for
41172062f5744557e270a38192554c3126ea5f97434Tim Northover/// instruction scheduling.
41272062f5744557e270a38192554c3126ea5f97434Tim NorthoverFunctionPass *llvm::createAArch64ISelDAG(AArch64TargetMachine &TM,
41372062f5744557e270a38192554c3126ea5f97434Tim Northover                                         CodeGenOpt::Level OptLevel) {
41472062f5744557e270a38192554c3126ea5f97434Tim Northover  return new AArch64DAGToDAGISel(TM, OptLevel);
41572062f5744557e270a38192554c3126ea5f97434Tim Northover}
416