mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
Hexagon: Add support for lowering block address.
llvm-svn: 176508
This commit is contained in:
parent
dc20aea70a
commit
ef3cf2b345
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
64
test/CodeGen/Hexagon/block-addr.ll
Normal file
64
test/CodeGen/Hexagon/block-addr.ll
Normal file
@ -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" }
|
14
test/CodeGen/Hexagon/indirect-br.ll
Normal file
14
test/CodeGen/Hexagon/indirect-br.ll
Normal file
@ -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
|
||||
}
|
Loading…
Reference in New Issue
Block a user