aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/ARM
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2010-05-11 01:19:40 +0000
committerEvan Cheng <evan.cheng@apple.com>2010-05-11 01:19:40 +0000
commit0ce537a9db2da085ab50b15d2454cb7cac460eb7 (patch)
tree3956c0627a8627afb7d67ee5ad927eb9bfa2ebc2 /lib/Target/ARM
parent81043ee5dc4cca470db8d45e080ba0a38efbffc2 (diff)
downloadexternal_llvm-0ce537a9db2da085ab50b15d2454cb7cac460eb7.zip
external_llvm-0ce537a9db2da085ab50b15d2454cb7cac460eb7.tar.gz
external_llvm-0ce537a9db2da085ab50b15d2454cb7cac460eb7.tar.bz2
Model some vst3 and vst4 with reg_sequence.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103453 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM')
-rw-r--r--lib/Target/ARM/ARMISelDAGToDAG.cpp44
-rw-r--r--lib/Target/ARM/NEONPreAllocPass.cpp16
2 files changed, 49 insertions, 11 deletions
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp
index 7f73556..294486c 100644
--- a/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -1049,14 +1049,16 @@ SDNode *ARMDAGToDAGISel::SelectVLD(SDNode *N, unsigned NumVecs,
return VLd;
assert(NumVecs <= 4);
+ SDValue RegSeq;
SDValue V0 = SDValue(VLd, 0);
SDValue V1 = SDValue(VLd, 1);
- SDValue RegSeq;
+ // Form a REG_SEQUENCE to force register allocation.
if (NumVecs == 2)
RegSeq = SDValue(PairDRegs(MVT::v2i64, V0, V1), 0);
else {
SDValue V2 = SDValue(VLd, 2);
+ // If it's a vld3, form a quad D-register but discard the last part.
SDValue V3 = (NumVecs == 3)
? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,VT), 0)
: SDValue(VLd, 3);
@@ -1183,12 +1185,44 @@ SDNode *ARMDAGToDAGISel::SelectVST(SDNode *N, unsigned NumVecs,
Ops.push_back(Align);
if (is64BitVector) {
- unsigned Opc = DOpcodes[OpcodeIndex];
- for (unsigned Vec = 0; Vec < NumVecs; ++Vec)
- Ops.push_back(N->getOperand(Vec+3));
+ if (llvm::ModelWithRegSequence() && NumVecs >= 2) {
+ assert(NumVecs <= 4);
+ SDValue RegSeq;
+ SDValue V0 = N->getOperand(0+3);
+ SDValue V1 = N->getOperand(1+3);
+
+ // Form a REG_SEQUENCE to force register allocation.
+ if (NumVecs == 2)
+ RegSeq = SDValue(PairDRegs(MVT::v2i64, V0, V1), 0);
+ else {
+ SDValue V2 = N->getOperand(2+3);
+ // If it's a vld3, form a quad D-register and leave the last part as
+ // an undef.
+ SDValue V3 = (NumVecs == 3)
+ ? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,dl,VT), 0)
+ : N->getOperand(3+3);
+ RegSeq = SDValue(QuadDRegs(MVT::v4i64, V0, V1, V2, V3), 0);
+ }
+
+ // Now extract the D registers back out.
+ Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_0, dl, VT,
+ RegSeq));
+ Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, VT,
+ RegSeq));
+ if (NumVecs > 2)
+ Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_2, dl, VT,
+ RegSeq));
+ if (NumVecs > 3)
+ Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_3, dl, VT,
+ RegSeq));
+ } else {
+ for (unsigned Vec = 0; Vec < NumVecs; ++Vec)
+ Ops.push_back(N->getOperand(Vec+3));
+ }
Ops.push_back(Pred);
Ops.push_back(Reg0); // predicate register
Ops.push_back(Chain);
+ unsigned Opc = DOpcodes[OpcodeIndex];
return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), NumVecs+5);
}
@@ -1198,7 +1232,7 @@ SDNode *ARMDAGToDAGISel::SelectVST(SDNode *N, unsigned NumVecs,
// storing pairs of D regs.
unsigned Opc = QOpcodes0[OpcodeIndex];
if (llvm::ModelWithRegSequence() && NumVecs == 2) {
- // First extract the quad D registers.
+ // First extract the pair of Q registers.
SDValue Q0 = N->getOperand(3);
SDValue Q1 = N->getOperand(4);
diff --git a/lib/Target/ARM/NEONPreAllocPass.cpp b/lib/Target/ARM/NEONPreAllocPass.cpp
index 538247a..5a5dd29 100644
--- a/lib/Target/ARM/NEONPreAllocPass.cpp
+++ b/lib/Target/ARM/NEONPreAllocPass.cpp
@@ -392,15 +392,19 @@ NEONPreAllocPass::FormsRegSequence(MachineInstr *MI,
VirtReg = DefMI->getOperand(1).getReg();
if (LastSrcReg && LastSrcReg != VirtReg)
return false;
+ LastSrcReg = VirtReg;
const TargetRegisterClass *RC = MRI->getRegClass(VirtReg);
- if (NumRegs == 2) {
- if (RC != ARM::QPRRegisterClass)
- return false;
- } else if (RC != ARM::QQPRRegisterClass)
+ if (RC != ARM::QPRRegisterClass && RC != ARM::QQPRRegisterClass)
return false;
unsigned SubIdx = DefMI->getOperand(2).getImm();
- if (LastSubIdx && LastSubIdx != SubIdx-1)
- return false;
+ if (LastSubIdx) {
+ if (LastSubIdx != SubIdx-1)
+ return false;
+ } else {
+ // Must start from arm_dsubreg_0 or arm_qsubreg_0.
+ if (SubIdx != ARM::DSUBREG_0 && SubIdx != ARM::QSUBREG_0)
+ return false;
+ }
LastSubIdx = SubIdx;
}
return true;