1 //===-- ARMSelectionDAGInfo.cpp - ARM SelectionDAG Info -------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the ARMSelectionDAGInfo class.
12 //===----------------------------------------------------------------------===//
14 #define DEBUG_TYPE "arm-selectiondag-info"
15 #include "ARMTargetMachine.h"
18 ARMSelectionDAGInfo::ARMSelectionDAGInfo(const TargetMachine
&TM
)
19 : TargetSelectionDAGInfo(TM
),
20 Subtarget(&TM
.getSubtarget
<ARMSubtarget
>()) {
23 ARMSelectionDAGInfo::~ARMSelectionDAGInfo() {
27 ARMSelectionDAGInfo::EmitTargetCodeForMemcpy(SelectionDAG
&DAG
, DebugLoc dl
,
29 SDValue Dst
, SDValue Src
,
30 SDValue Size
, unsigned Align
,
31 bool isVolatile
, bool AlwaysInline
,
32 MachinePointerInfo DstPtrInfo
,
33 MachinePointerInfo SrcPtrInfo
) const {
34 // Do repeated 4-byte loads and stores. To be improved.
35 // This requires 4-byte alignment.
38 // This requires the copy size to be a constant, preferrably
39 // within a subtarget-specific limit.
40 ConstantSDNode
*ConstantSize
= dyn_cast
<ConstantSDNode
>(Size
);
43 uint64_t SizeVal
= ConstantSize
->getZExtValue();
44 if (!AlwaysInline
&& SizeVal
> Subtarget
->getMaxInlineSizeThreshold())
47 unsigned BytesLeft
= SizeVal
& 3;
48 unsigned NumMemOps
= SizeVal
>> 2;
49 unsigned EmittedNumMemOps
= 0;
53 const unsigned MAX_LOADS_IN_LDM
= 6;
54 SDValue TFOps
[MAX_LOADS_IN_LDM
];
55 SDValue Loads
[MAX_LOADS_IN_LDM
];
56 uint64_t SrcOff
= 0, DstOff
= 0;
58 // Emit up to MAX_LOADS_IN_LDM loads, then a TokenFactor barrier, then the
59 // same number of stores. The loads and stores will get combined into
61 while (EmittedNumMemOps
< NumMemOps
) {
63 i
< MAX_LOADS_IN_LDM
&& EmittedNumMemOps
+ i
< NumMemOps
; ++i
) {
64 Loads
[i
] = DAG
.getLoad(VT
, dl
, Chain
,
65 DAG
.getNode(ISD::ADD
, dl
, MVT::i32
, Src
,
66 DAG
.getConstant(SrcOff
, MVT::i32
)),
67 SrcPtrInfo
.getWithOffset(SrcOff
), isVolatile
,
69 TFOps
[i
] = Loads
[i
].getValue(1);
72 Chain
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
, &TFOps
[0], i
);
75 i
< MAX_LOADS_IN_LDM
&& EmittedNumMemOps
+ i
< NumMemOps
; ++i
) {
76 TFOps
[i
] = DAG
.getStore(Chain
, dl
, Loads
[i
],
77 DAG
.getNode(ISD::ADD
, dl
, MVT::i32
, Dst
,
78 DAG
.getConstant(DstOff
, MVT::i32
)),
79 DstPtrInfo
.getWithOffset(DstOff
),
80 isVolatile
, false, 0);
83 Chain
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
, &TFOps
[0], i
);
85 EmittedNumMemOps
+= i
;
91 // Issue loads / stores for the trailing (1 - 3) bytes.
92 unsigned BytesLeftSave
= BytesLeft
;
103 Loads
[i
] = DAG
.getLoad(VT
, dl
, Chain
,
104 DAG
.getNode(ISD::ADD
, dl
, MVT::i32
, Src
,
105 DAG
.getConstant(SrcOff
, MVT::i32
)),
106 SrcPtrInfo
.getWithOffset(SrcOff
), false, false, 0);
107 TFOps
[i
] = Loads
[i
].getValue(1);
112 Chain
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
, &TFOps
[0], i
);
115 BytesLeft
= BytesLeftSave
;
117 if (BytesLeft
>= 2) {
125 TFOps
[i
] = DAG
.getStore(Chain
, dl
, Loads
[i
],
126 DAG
.getNode(ISD::ADD
, dl
, MVT::i32
, Dst
,
127 DAG
.getConstant(DstOff
, MVT::i32
)),
128 DstPtrInfo
.getWithOffset(DstOff
), false, false, 0);
133 return DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
, &TFOps
[0], i
);