aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJyotsna Verma <jverma@codeaurora.org>2013-03-07 19:10:28 +0000
committerJyotsna Verma <jverma@codeaurora.org>2013-03-07 19:10:28 +0000
commitb6716187ca8cc33817fb7446d9d9bdcb708c3f35 (patch)
treece3a0bc79e3ce215e4288621af4182a84ef047d3
parentccd38f4efb7f1a4457234d95e30fec5bcc738700 (diff)
Hexagon: Add support to lower block address.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@176637 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/Hexagon/HexagonISelLowering.cpp12
-rw-r--r--lib/Target/Hexagon/HexagonISelLowering.h2
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfo.td9
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfoV4.td5
-rw-r--r--test/CodeGen/Hexagon/block-addr.ll64
-rw-r--r--test/CodeGen/Hexagon/indirect-br.ll14
6 files changed, 106 insertions, 0 deletions
diff --git a/lib/Target/Hexagon/HexagonISelLowering.cpp b/lib/Target/Hexagon/HexagonISelLowering.cpp
index e5c5400d08..c142ed92c4 100644
--- a/lib/Target/Hexagon/HexagonISelLowering.cpp
+++ b/lib/Target/Hexagon/HexagonISelLowering.cpp
@@ -1024,6 +1024,14 @@ SDValue HexagonTargetLowering::LowerGLOBALADDRESS(SDValue Op,
return DAG.getNode(HexagonISD::CONST32, dl, getPointerTy(), Result);
}
+SDValue
+HexagonTargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const {
+ const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
+ SDValue BA_SD = DAG.getTargetBlockAddress(BA, MVT::i32);
+ DebugLoc dl = Op.getDebugLoc();
+ return DAG.getNode(HexagonISD::CONST32_GP, dl, getPointerTy(), BA_SD);
+}
+
//===----------------------------------------------------------------------===//
// TargetLowering Implementation
//===----------------------------------------------------------------------===//
@@ -1297,6 +1305,7 @@ HexagonTargetLowering::HexagonTargetLowering(HexagonTargetMachine
// Custom legalize GlobalAddress nodes into CONST32.
setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
setOperationAction(ISD::GlobalAddress, MVT::i8, Custom);
+ setOperationAction(ISD::BlockAddress, MVT::i32, Custom);
// Truncate action?
setOperationAction(ISD::TRUNCATE, MVT::i64, Expand);
@@ -1459,6 +1468,8 @@ HexagonTargetLowering::getTargetNodeName(unsigned Opcode) const {
switch (Opcode) {
default: return 0;
case HexagonISD::CONST32: return "HexagonISD::CONST32";
+ case HexagonISD::CONST32_GP: return "HexagonISD::CONST32_GP";
+ case HexagonISD::CONST32_Int_Real: return "HexagonISD::CONST32_Int_Real";
case HexagonISD::ADJDYNALLOC: return "HexagonISD::ADJDYNALLOC";
case HexagonISD::CMPICC: return "HexagonISD::CMPICC";
case HexagonISD::CMPFCC: return "HexagonISD::CMPFCC";
@@ -1507,6 +1518,7 @@ HexagonTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
case ISD::MEMBARRIER: return LowerMEMBARRIER(Op, DAG);
case ISD::ATOMIC_FENCE: return LowerATOMIC_FENCE(Op, DAG);
case ISD::GlobalAddress: return LowerGLOBALADDRESS(Op, DAG);
+ case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
case ISD::VASTART: return LowerVASTART(Op, DAG);
case ISD::BR_JT: return LowerBR_JT(Op, DAG);
diff --git a/lib/Target/Hexagon/HexagonISelLowering.h b/lib/Target/Hexagon/HexagonISelLowering.h
index 65dab8597b..3279cc6524 100644
--- a/lib/Target/Hexagon/HexagonISelLowering.h
+++ b/lib/Target/Hexagon/HexagonISelLowering.h
@@ -27,6 +27,7 @@ namespace llvm {
CONST32,
CONST32_GP, // For marking data present in GP.
+ CONST32_Int_Real,
FCONST32,
SETCC,
ADJDYNALLOC,
@@ -106,6 +107,7 @@ namespace llvm {
DebugLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
SDValue LowerGLOBALADDRESS(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const;
diff --git a/lib/Target/Hexagon/HexagonInstrInfo.td b/lib/Target/Hexagon/HexagonInstrInfo.td
index 72f05355eb..1e63ed2a9c 100644
--- a/lib/Target/Hexagon/HexagonInstrInfo.td
+++ b/lib/Target/Hexagon/HexagonInstrInfo.td
@@ -2076,6 +2076,10 @@ def CONST32_Int_Real : LDInst2<(outs IntRegs:$dst), (ins i32imm:$global),
"$dst = CONST32(#$global)",
[(set (i32 IntRegs:$dst), imm:$global) ]>;
+// Map BlockAddress lowering to CONST32_Int_Real
+def : Pat<(HexagonCONST32_GP tblockaddress:$addr),
+ (CONST32_Int_Real tblockaddress:$addr)>;
+
let isReMaterializable = 1, isMoveImm = 1 in
def CONST32_Label : LDInst2<(outs IntRegs:$dst), (ins bblabel:$label),
"$dst = CONST32($label)",
@@ -3046,6 +3050,11 @@ def BR_JT : JRInst<(outs), (ins IntRegs:$src),
"jumpr $src",
[(HexagonBR_JT (i32 IntRegs:$src))]>;
+let isBranch=1, isIndirectBranch=1, isTerminator=1 in
+def BRIND : JRInst<(outs), (ins IntRegs:$src),
+ "jumpr $src",
+ [(brind (i32 IntRegs:$src))]>;
+
def HexagonWrapperJT: SDNode<"HexagonISD::WrapperJT", SDTIntUnaryOp>;
def : Pat<(HexagonWrapperJT tjumptable:$dst),
diff --git a/lib/Target/Hexagon/HexagonInstrInfoV4.td b/lib/Target/Hexagon/HexagonInstrInfoV4.td
index e1b2f88bfa..d5e2d0c71a 100644
--- a/lib/Target/Hexagon/HexagonInstrInfoV4.td
+++ b/lib/Target/Hexagon/HexagonInstrInfoV4.td
@@ -3790,6 +3790,11 @@ def TFRI_V4 : ALU32_ri<(outs IntRegs:$dst), (ins globaladdress:$src1),
[(set IntRegs:$dst, (HexagonCONST32 tglobaladdr:$src1))]>,
Requires<[HasV4T]>;
+// Transfer a block address into a register
+def : Pat<(HexagonCONST32_GP tblockaddress:$src1),
+ (TFRI_V4 tblockaddress:$src1)>,
+ Requires<[HasV4T]>;
+
let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in
def TFRI_cPt_V4 : ALU32_ri<(outs IntRegs:$dst),
(ins PredRegs:$src1, globaladdress:$src2),
diff --git a/test/CodeGen/Hexagon/block-addr.ll b/test/CodeGen/Hexagon/block-addr.ll
new file mode 100644
index 0000000000..54a12bf484
--- /dev/null
+++ b/test/CodeGen/Hexagon/block-addr.ll
@@ -0,0 +1,64 @@
+; RUN: llc -march=hexagon < %s | FileCheck %s
+
+; CHECK: r{{[0-9]+}} = CONST32(#.LJTI{{[0-9]+_[0-9]+}})
+; CHECK: r{{[0-9]+}} = memw(r{{[0-9]+}}+r{{[0-9]+<<#[0-9]+}})
+; CHECK: jumpr r{{[0-9]+}}
+
+define void @main() #0 {
+entry:
+ %ret = alloca i32, align 4
+ br label %while.body
+
+while.body:
+ %ret.0.load17 = load volatile i32* %ret, align 4
+ switch i32 %ret.0.load17, label %label6 [
+ i32 0, label %label0
+ i32 1, label %label1
+ i32 2, label %label2
+ i32 3, label %label3
+ i32 4, label %label4
+ i32 5, label %label5
+ ]
+
+label0:
+ %ret.0.load18 = load volatile i32* %ret, align 4
+ %inc = add nsw i32 %ret.0.load18, 1
+ store volatile i32 %inc, i32* %ret, align 4
+ br label %while.body
+
+label1:
+ %ret.0.load19 = load volatile i32* %ret, align 4
+ %inc2 = add nsw i32 %ret.0.load19, 1
+ store volatile i32 %inc2, i32* %ret, align 4
+ br label %while.body
+
+label2:
+ %ret.0.load20 = load volatile i32* %ret, align 4
+ %inc4 = add nsw i32 %ret.0.load20, 1
+ store volatile i32 %inc4, i32* %ret, align 4
+ br label %while.body
+
+label3:
+ %ret.0.load21 = load volatile i32* %ret, align 4
+ %inc6 = add nsw i32 %ret.0.load21, 1
+ store volatile i32 %inc6, i32* %ret, align 4
+ br label %while.body
+
+label4:
+ %ret.0.load22 = load volatile i32* %ret, align 4
+ %inc8 = add nsw i32 %ret.0.load22, 1
+ store volatile i32 %inc8, i32* %ret, align 4
+ br label %while.body
+
+label5:
+ %ret.0.load23 = load volatile i32* %ret, align 4
+ %inc10 = add nsw i32 %ret.0.load23, 1
+ store volatile i32 %inc10, i32* %ret, align 4
+ br label %while.body
+
+label6:
+ store volatile i32 0, i32* %ret, align 4
+ br label %while.body
+}
+
+attributes #0 = { noreturn nounwind "target-cpu"="hexagonv4" }
diff --git a/test/CodeGen/Hexagon/indirect-br.ll b/test/CodeGen/Hexagon/indirect-br.ll
new file mode 100644
index 0000000000..919e501891
--- /dev/null
+++ b/test/CodeGen/Hexagon/indirect-br.ll
@@ -0,0 +1,14 @@
+; RUN: llc -march=hexagon < %s | FileCheck %s
+
+;CHECK: jumpr r{{[0-9]+}}
+
+define i32 @check_indirect_br(i8* %target) nounwind {
+entry:
+ indirectbr i8* %target, [label %test_label]
+
+test_label:
+ br label %ret
+
+ret:
+ ret i32 -1
+} \ No newline at end of file