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