summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorKevin Qin <Kevin.Qin@arm.com>2013-12-18 06:26:04 +0000
committerKevin Qin <Kevin.Qin@arm.com>2013-12-18 06:26:04 +0000
commit0a9ff8776b5fcffdb5292f261da04085ea8e116f (patch)
tree6a80763175ed1c8cc9537463b4530cec6051dc46 /lib
parent5a445395de7a5481ed8a5d1768aa9e3db83bd18a (diff)
downloadllvm-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.cpp9
-rw-r--r--lib/Target/AArch64/AArch64ISelLowering.cpp32
-rw-r--r--lib/Target/AArch64/AArch64ISelLowering.h2
-rw-r--r--lib/Target/AArch64/AArch64InstrInfo.td1
-rw-r--r--lib/Target/AArch64/AArch64InstrNEON.td44
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
//===----------------------------------------------------------------------===//