diff options
author | Kevin Qin <Kevin.Qin@arm.com> | 2013-12-18 06:26:04 +0000 |
---|---|---|
committer | Kevin Qin <Kevin.Qin@arm.com> | 2013-12-18 06:26:04 +0000 |
commit | 0a9ff8776b5fcffdb5292f261da04085ea8e116f (patch) | |
tree | 6a80763175ed1c8cc9537463b4530cec6051dc46 /lib | |
parent | 5a445395de7a5481ed8a5d1768aa9e3db83bd18a (diff) | |
download | llvm-0a9ff8776b5fcffdb5292f261da04085ea8e116f.tar.gz llvm-0a9ff8776b5fcffdb5292f261da04085ea8e116f.tar.bz2 llvm-0a9ff8776b5fcffdb5292f261da04085ea8e116f.tar.xz |
[AArch64 NEON]Implment loading vector constant form constant pool.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197551 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/AArch64/AArch64ISelDAGToDAG.cpp | 9 | ||||
-rw-r--r-- | lib/Target/AArch64/AArch64ISelLowering.cpp | 32 | ||||
-rw-r--r-- | lib/Target/AArch64/AArch64ISelLowering.h | 2 | ||||
-rw-r--r-- | lib/Target/AArch64/AArch64InstrInfo.td | 1 | ||||
-rw-r--r-- | lib/Target/AArch64/AArch64InstrNEON.td | 44 |
5 files changed, 79 insertions, 9 deletions
diff --git a/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp index ef99541c17..dac4b32cfe 100644 --- a/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp +++ b/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp @@ -1113,15 +1113,6 @@ SDNode *AArch64DAGToDAGISel::Select(SDNode *Node) { return CurDAG->SelectNodeTo(Node, AArch64::ADDxxi_lsl0_s, PtrTy, TFI, CurDAG->getTargetConstant(0, PtrTy)); } - case ISD::ConstantPool: { - // Constant pools are fine, just create a Target entry. - ConstantPoolSDNode *CN = cast<ConstantPoolSDNode>(Node); - const Constant *C = CN->getConstVal(); - SDValue CP = CurDAG->getTargetConstantPool(C, CN->getValueType(0)); - - ReplaceUses(SDValue(Node, 0), CP); - return NULL; - } case ISD::Constant: { SDNode *ResNode = 0; if (cast<ConstantSDNode>(Node)->getZExtValue() == 0) { diff --git a/lib/Target/AArch64/AArch64ISelLowering.cpp b/lib/Target/AArch64/AArch64ISelLowering.cpp index 3266fc2dcc..1b75d0571a 100644 --- a/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -140,6 +140,7 @@ AArch64TargetLowering::AArch64TargetLowering(AArch64TargetMachine &TM) setOperationAction(ISD::VAARG, MVT::Other, Expand); setOperationAction(ISD::BlockAddress, MVT::i64, Custom); + setOperationAction(ISD::ConstantPool, MVT::i64, Custom); setOperationAction(ISD::ROTL, MVT::i32, Expand); setOperationAction(ISD::ROTL, MVT::i64, Expand); @@ -2268,6 +2269,36 @@ AArch64TargetLowering::LowerGlobalAddressELF(SDValue Op, } } +SDValue +AArch64TargetLowering::LowerConstantPool(SDValue Op, + SelectionDAG &DAG) const { + SDLoc DL(Op); + EVT PtrVT = getPointerTy(); + ConstantPoolSDNode *CN = cast<ConstantPoolSDNode>(Op); + const Constant *C = CN->getConstVal(); + + switch(getTargetMachine().getCodeModel()) { + case CodeModel::Small: + // The most efficient code is PC-relative anyway for the small memory model, + // so we don't need to worry about relocation model. + return DAG.getNode(AArch64ISD::WrapperSmall, DL, PtrVT, + DAG.getTargetConstantPool(C, PtrVT, 0, 0, + AArch64II::MO_NO_FLAG), + DAG.getTargetConstantPool(C, PtrVT, 0, 0, + AArch64II::MO_LO12), + DAG.getConstant(CN->getAlignment(), MVT::i32)); + case CodeModel::Large: + return DAG.getNode( + AArch64ISD::WrapperLarge, DL, PtrVT, + DAG.getTargetConstantPool(C, PtrVT, 0, 0, AArch64II::MO_ABS_G3), + DAG.getTargetConstantPool(C, PtrVT, 0, 0, AArch64II::MO_ABS_G2_NC), + DAG.getTargetConstantPool(C, PtrVT, 0, 0, AArch64II::MO_ABS_G1_NC), + DAG.getTargetConstantPool(C, PtrVT, 0, 0, AArch64II::MO_ABS_G0_NC)); + default: + llvm_unreachable("Only small and large code models supported now"); + } +} + SDValue AArch64TargetLowering::LowerTLSDescCall(SDValue SymAddr, SDValue DescAddr, SDLoc DL, @@ -2898,6 +2929,7 @@ AArch64TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { case ISD::BRCOND: return LowerBRCOND(Op, DAG); case ISD::BR_CC: return LowerBR_CC(Op, DAG); case ISD::GlobalAddress: return LowerGlobalAddressELF(Op, DAG); + case ISD::ConstantPool: return LowerConstantPool(Op, DAG); case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); case ISD::JumpTable: return LowerJumpTable(Op, DAG); case ISD::SELECT: return LowerSELECT(Op, DAG); diff --git a/lib/Target/AArch64/AArch64ISelLowering.h b/lib/Target/AArch64/AArch64ISelLowering.h index bb0523a2bd..358b5a1b21 100644 --- a/lib/Target/AArch64/AArch64ISelLowering.h +++ b/lib/Target/AArch64/AArch64ISelLowering.h @@ -306,6 +306,8 @@ public: SDValue LowerGlobalAddressELFLarge(SDValue Op, SelectionDAG &DAG) const; SDValue LowerGlobalAddressELF(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerTLSDescCall(SDValue SymAddr, SDValue DescAddr, SDLoc DL, SelectionDAG &DAG) const; SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; diff --git a/lib/Target/AArch64/AArch64InstrInfo.td b/lib/Target/AArch64/AArch64InstrInfo.td index 23d81fc478..4c35b466f1 100644 --- a/lib/Target/AArch64/AArch64InstrInfo.td +++ b/lib/Target/AArch64/AArch64InstrInfo.td @@ -4539,6 +4539,7 @@ def : ADRP_ADD<A64WrapperSmall, texternalsym>; def : ADRP_ADD<A64WrapperSmall, tglobaladdr>; def : ADRP_ADD<A64WrapperSmall, tglobaltlsaddr>; def : ADRP_ADD<A64WrapperSmall, tjumptable>; +def : ADRP_ADD<A64WrapperSmall, tconstpool>; //===----------------------------------------------------------------------===// // GOT access patterns diff --git a/lib/Target/AArch64/AArch64InstrNEON.td b/lib/Target/AArch64/AArch64InstrNEON.td index fbf1a47168..3ddeed4d93 100644 --- a/lib/Target/AArch64/AArch64InstrNEON.td +++ b/lib/Target/AArch64/AArch64InstrNEON.td @@ -70,6 +70,50 @@ def assertsext : SDNode<"ISD::AssertSext", SDT_assertext>; def assertzext : SDNode<"ISD::AssertZext", SDT_assertext>; //===----------------------------------------------------------------------===// +// Addressing-mode instantiations +//===----------------------------------------------------------------------===// + +multiclass ls_64_pats<dag address, dag Base, dag Offset, ValueType Ty> { +defm : ls_neutral_pats<LSFP64_LDR, LSFP64_STR, Base, + !foreach(decls.pattern, Offset, + !subst(OFFSET, dword_uimm12, decls.pattern)), + !foreach(decls.pattern, address, + !subst(OFFSET, dword_uimm12, + !subst(ALIGN, min_align8, decls.pattern))), + Ty>; +} + +multiclass ls_128_pats<dag address, dag Base, dag Offset, ValueType Ty> { +defm : ls_neutral_pats<LSFP128_LDR, LSFP128_STR, Base, + !foreach(decls.pattern, Offset, + !subst(OFFSET, qword_uimm12, decls.pattern)), + !foreach(decls.pattern, address, + !subst(OFFSET, qword_uimm12, + !subst(ALIGN, min_align16, decls.pattern))), + Ty>; +} + +multiclass uimm12_neon_pats<dag address, dag Base, dag Offset> { + defm : ls_64_pats<address, Base, Offset, v8i8>; + defm : ls_64_pats<address, Base, Offset, v4i16>; + defm : ls_64_pats<address, Base, Offset, v2i32>; + defm : ls_64_pats<address, Base, Offset, v1i64>; + defm : ls_64_pats<address, Base, Offset, v2f32>; + defm : ls_64_pats<address, Base, Offset, v1f64>; + + defm : ls_128_pats<address, Base, Offset, v16i8>; + defm : ls_128_pats<address, Base, Offset, v8i16>; + defm : ls_128_pats<address, Base, Offset, v4i32>; + defm : ls_128_pats<address, Base, Offset, v2i64>; + defm : ls_128_pats<address, Base, Offset, v4f32>; + defm : ls_128_pats<address, Base, Offset, v2f64>; +} + +defm : uimm12_neon_pats<(A64WrapperSmall + tconstpool:$Hi, tconstpool:$Lo12, ALIGN), + (ADRPxi tconstpool:$Hi), (i64 tconstpool:$Lo12)>; + +//===----------------------------------------------------------------------===// // Multiclasses //===----------------------------------------------------------------------===// |