summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2010-05-06 06:36:08 +0000
committerEvan Cheng <evan.cheng@apple.com>2010-05-06 06:36:08 +0000
commitb63387afc6b10e88631d1ef232c41ab6c18c8581 (patch)
tree1966e3763e96557663146122e5f03d78fe633855
parent62bb2f63f92fa00e0a89e4dabef030a5b441905c (diff)
downloadllvm-b63387afc6b10e88631d1ef232c41ab6c18c8581.tar.gz
llvm-b63387afc6b10e88631d1ef232c41ab6c18c8581.tar.bz2
llvm-b63387afc6b10e88631d1ef232c41ab6c18c8581.tar.xz
Re-apply 103156 and 103157. 103156 didn't break anything. 10315 exposed a coalescer bug that's fixed by 103170.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103172 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.cpp51
-rw-r--r--lib/Target/ARM/ARMBaseRegisterInfo.cpp41
-rw-r--r--lib/Target/ARM/ARMInstrNEON.td5
-rw-r--r--lib/Target/ARM/ARMRegisterInfo.h3
-rw-r--r--lib/Target/ARM/ARMRegisterInfo.td69
-rw-r--r--lib/Target/X86/X86RegisterInfo.cpp2
-rw-r--r--utils/TableGen/EDEmitter.cpp5
7 files changed, 150 insertions, 26 deletions
diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp
index 0cf85e86af..d886a1f81b 100644
--- a/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -540,16 +540,17 @@ bool
ARMBaseInstrInfo::isMoveInstr(const MachineInstr &MI,
unsigned &SrcReg, unsigned &DstReg,
unsigned& SrcSubIdx, unsigned& DstSubIdx) const {
- SrcSubIdx = DstSubIdx = 0; // No sub-registers.
-
switch (MI.getOpcode()) {
default: break;
case ARM::VMOVS:
case ARM::VMOVD:
case ARM::VMOVDneon:
- case ARM::VMOVQ: {
+ case ARM::VMOVQ:
+ case ARM::VMOVQQ : {
SrcReg = MI.getOperand(1).getReg();
DstReg = MI.getOperand(0).getReg();
+ SrcSubIdx = MI.getOperand(1).getSubReg();
+ DstSubIdx = MI.getOperand(0).getSubReg();
return true;
}
case ARM::MOVr:
@@ -564,6 +565,8 @@ ARMBaseInstrInfo::isMoveInstr(const MachineInstr &MI,
"Invalid ARM MOV instruction");
SrcReg = MI.getOperand(1).getReg();
DstReg = MI.getOperand(0).getReg();
+ SrcSubIdx = MI.getOperand(1).getSubReg();
+ DstSubIdx = MI.getOperand(0).getSubReg();
return true;
}
}
@@ -679,6 +682,14 @@ ARMBaseInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
SrcRC == ARM::QPR_8RegisterClass)
SrcRC = ARM::QPRRegisterClass;
+ // Allow QQPR / QQPR_VFP2 / QQPR_8 cross-class copies.
+ if (DestRC == ARM::QQPR_VFP2RegisterClass ||
+ DestRC == ARM::QQPR_8RegisterClass)
+ DestRC = ARM::QQPRRegisterClass;
+ if (SrcRC == ARM::QQPR_VFP2RegisterClass ||
+ SrcRC == ARM::QQPR_8RegisterClass)
+ SrcRC = ARM::QQPRRegisterClass;
+
// Disallow copies of unequal sizes.
if (DestRC != SrcRC && DestRC->getSize() != SrcRC->getSize())
return false;
@@ -703,11 +714,12 @@ ARMBaseInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
Opc = ARM::VMOVDneon;
else if (DestRC == ARM::QPRRegisterClass)
Opc = ARM::VMOVQ;
+ else if (DestRC == ARM::QQPRRegisterClass)
+ Opc = ARM::VMOVQQ;
else
return false;
- AddDefaultPred(BuildMI(MBB, I, DL, get(Opc), DestReg)
- .addReg(SrcReg));
+ AddDefaultPred(BuildMI(MBB, I, DL, get(Opc), DestReg).addReg(SrcReg));
}
return true;
@@ -748,12 +760,11 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTRD))
.addReg(SrcReg, getKillRegState(isKill))
.addFrameIndex(FI).addImm(0).addMemOperand(MMO));
- } else {
- assert((RC == ARM::QPRRegisterClass ||
- RC == ARM::QPR_VFP2RegisterClass ||
- RC == ARM::QPR_8RegisterClass) && "Unknown regclass!");
+ } else if (RC == ARM::QPRRegisterClass ||
+ RC == ARM::QPR_VFP2RegisterClass ||
+ RC == ARM::QPR_8RegisterClass) {
// FIXME: Neon instructions should support predicates
- if (Align >= 16 && (getRegisterInfo().canRealignStack(MF))) {
+ if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) {
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VST1q))
.addFrameIndex(FI).addImm(128)
.addMemOperand(MMO)
@@ -765,6 +776,11 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
.addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4))
.addMemOperand(MMO));
}
+ } else {
+ assert((RC == ARM::QQPRRegisterClass ||
+ RC == ARM::QQPR_VFP2RegisterClass ||
+ RC == ARM::QQPR_8RegisterClass) && "Unknown regclass!");
+ llvm_unreachable("Not yet implemented!");
}
}
@@ -800,12 +816,10 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
RC == ARM::DPR_8RegisterClass) {
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDRD), DestReg)
.addFrameIndex(FI).addImm(0).addMemOperand(MMO));
- } else {
- assert((RC == ARM::QPRRegisterClass ||
- RC == ARM::QPR_VFP2RegisterClass ||
- RC == ARM::QPR_8RegisterClass) && "Unknown regclass!");
- if (Align >= 16
- && (getRegisterInfo().canRealignStack(MF))) {
+ } else if (RC == ARM::QPRRegisterClass ||
+ RC == ARM::QPR_VFP2RegisterClass ||
+ RC == ARM::QPR_8RegisterClass) {
+ if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) {
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLD1q), DestReg)
.addFrameIndex(FI).addImm(128)
.addMemOperand(MMO));
@@ -815,6 +829,11 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
.addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4))
.addMemOperand(MMO));
}
+ } else {
+ assert((RC == ARM::QQPRRegisterClass ||
+ RC == ARM::QQPR_VFP2RegisterClass ||
+ RC == ARM::QQPR_8RegisterClass) && "Unknown regclass!");
+ llvm_unreachable("Not yet implemented!");
}
}
diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index bc12187436..bf779ccf55 100644
--- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -262,7 +262,7 @@ ARMBaseRegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A,
case 1:
case 2:
case 3:
- case 4:
+ case 4: {
// S sub-registers.
if (A->getSize() == 8) {
if (B == &ARM::SPR_8RegClass)
@@ -273,19 +273,48 @@ ARMBaseRegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A,
return &ARM::DPR_VFP2RegClass;
}
- assert(A->getSize() == 16 && "Expecting a Q register class!");
+ if (A->getSize() == 16) {
+ if (B == &ARM::SPR_8RegClass)
+ return &ARM::QPR_8RegClass;
+ return &ARM::QPR_VFP2RegClass;
+ }
+
+ assert(A->getSize() == 32 && "Expecting a QQ register class!");
if (B == &ARM::SPR_8RegClass)
- return &ARM::QPR_8RegClass;
- return &ARM::QPR_VFP2RegClass;
+ return &ARM::QQPR_8RegClass;
+ return &ARM::QQPR_VFP2RegClass;
+ }
case 5:
case 6:
+ case 7:
+ case 8: {
// D sub-registers.
+ if (A->getSize() == 16) {
+ if (B == &ARM::DPR_VFP2RegClass)
+ return &ARM::QPR_VFP2RegClass;
+ if (B == &ARM::DPR_8RegClass)
+ return &ARM::QPR_8RegClass;
+ return A;
+ }
+
+ assert(A->getSize() == 32 && "Expecting a QQ register class!");
if (B == &ARM::DPR_VFP2RegClass)
- return &ARM::QPR_VFP2RegClass;
+ return &ARM::QQPR_VFP2RegClass;
if (B == &ARM::DPR_8RegClass)
- return &ARM::QPR_8RegClass;
+ return &ARM::QQPR_8RegClass;
return A;
}
+ case 9:
+ case 10: {
+ // Q sub-registers.
+ assert(A->getSize() == 32 && "Expecting a QQ register class!");
+ if (B == &ARM::QPR_VFP2RegClass)
+ return &ARM::QQPR_VFP2RegClass;
+ if (B == &ARM::QPR_8RegClass)
+ return &ARM::QQPR_8RegClass;
+ return A;
+ }
+ }
return 0;
}
diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td
index d5ce2b8468..9577e0bffc 100644
--- a/lib/Target/ARM/ARMInstrNEON.td
+++ b/lib/Target/ARM/ARMInstrNEON.td
@@ -2834,6 +2834,11 @@ def VMOVDneon: N3VX<0, 0, 0b10, 0b0001, 0, 1, (outs DPR:$dst), (ins DPR:$src),
def VMOVQ : N3VX<0, 0, 0b10, 0b0001, 1, 1, (outs QPR:$dst), (ins QPR:$src),
N3RegFrm, IIC_VMOVD, "vmov", "$dst, $src", "", []>;
+// Pseudo vector move instruction for QQ (a pair of Q) registers. This should
+// be expanded after register allocation is completed.
+def VMOVQQ : PseudoInst<(outs QQPR:$dst), (ins QQPR:$src),
+ NoItinerary, "@ vmov\t$dst, $src", []>;
+
// VMOV : Vector Move (Immediate)
// VMOV_get_imm8 xform function: convert build_vector to VMOV.i8 imm.
diff --git a/lib/Target/ARM/ARMRegisterInfo.h b/lib/Target/ARM/ARMRegisterInfo.h
index 041afd0414..f13c7d4acc 100644
--- a/lib/Target/ARM/ARMRegisterInfo.h
+++ b/lib/Target/ARM/ARMRegisterInfo.h
@@ -29,7 +29,8 @@ namespace ARM {
/// ARMRegisterInfo.td file.
enum SubregIndex {
SSUBREG_0 = 1, SSUBREG_1 = 2, SSUBREG_2 = 3, SSUBREG_3 = 4,
- DSUBREG_0 = 5, DSUBREG_1 = 6
+ DSUBREG_0 = 5, DSUBREG_1 = 6, DSUBREG_2 = 7, DSUBREG_3 = 8,
+ QSUBREG_0 = 9, QSUBREG_1 = 10
};
}
diff --git a/lib/Target/ARM/ARMRegisterInfo.td b/lib/Target/ARM/ARMRegisterInfo.td
index 0d4200c63d..29907caa3f 100644
--- a/lib/Target/ARM/ARMRegisterInfo.td
+++ b/lib/Target/ARM/ARMRegisterInfo.td
@@ -106,6 +106,17 @@ def Q13 : ARMReg<13, "q13", [D26, D27]>;
def Q14 : ARMReg<14, "q14", [D28, D29]>;
def Q15 : ARMReg<15, "q15", [D30, D31]>;
+// Pseudo 256-bit registers to represent pairs of Q registers. These should
+// never be present in the emitted code.
+def QQ0 : ARMReg<0, "qq0", [Q0, Q1]>;
+def QQ1 : ARMReg<1, "qq1", [Q2, Q3]>;
+def QQ2 : ARMReg<2, "qq2", [Q4, Q5]>;
+def QQ3 : ARMReg<3, "qq3", [Q6, Q7]>;
+def QQ4 : ARMReg<4, "qq4", [Q8, Q9]>;
+def QQ5 : ARMReg<5, "qq5", [Q10, Q11]>;
+def QQ6 : ARMReg<6, "qq6", [Q12, Q13]>;
+def QQ7 : ARMReg<7, "qq7", [Q14, Q15]>;
+
// Current Program Status Register.
def CPSR : ARMReg<0, "cpsr">;
@@ -364,6 +375,32 @@ def QPR_8 : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
let SubRegClassList = [SPR_8, SPR_8, SPR_8, SPR_8, DPR_8, DPR_8];
}
+// Pseudo 256-bit vector register class to model pairs of Q registers.
+def QQPR : RegisterClass<"ARM", [v4i64],
+ 256,
+ [QQ0, QQ1, QQ2, QQ3, QQ4, QQ5, QQ6, QQ7]> {
+ let SubRegClassList = [SPR_INVALID, SPR_INVALID, SPR_INVALID, SPR_INVALID,
+ DPR, DPR, DPR, DPR, QPR, QPR];
+}
+
+// Subset of QQPR that have 32-bit SPR subregs.
+def QQPR_VFP2 : RegisterClass<"ARM", [v4i64],
+ 256,
+ [QQ0, QQ1, QQ2, QQ3]> {
+ let SubRegClassList = [SPR, SPR, SPR, SPR,
+ DPR_VFP2, DPR_VFP2, DPR_VFP2, DPR_VFP2,
+ QPR_VFP2, QPR_VFP2];
+}
+
+// Subset of QQPR that have QPR_8, DPR_8, and SPR_8 subregs.
+def QQPR_8 : RegisterClass<"ARM", [v4i64],
+ 256,
+ [QQ0, QQ1]> {
+ let SubRegClassList = [SPR_8, SPR_8, SPR_8, SPR_8,
+ DPR_8, DPR_8, DPR_8, DPR_8,
+ QPR_8, QPR_8];
+}
+
// Condition code registers.
def CCR : RegisterClass<"ARM", [i32], 32, [CPSR]>;
@@ -378,6 +415,10 @@ def arm_ssubreg_2 : PatLeaf<(i32 3)>;
def arm_ssubreg_3 : PatLeaf<(i32 4)>;
def arm_dsubreg_0 : PatLeaf<(i32 5)>;
def arm_dsubreg_1 : PatLeaf<(i32 6)>;
+def arm_dsubreg_2 : PatLeaf<(i32 7)>;
+def arm_dsubreg_3 : PatLeaf<(i32 8)>;
+def arm_qsubreg_0 : PatLeaf<(i32 9)>;
+def arm_qsubreg_1 : PatLeaf<(i32 10)>;
// S sub-registers of D registers.
def : SubRegSet<1, [D0, D1, D2, D3, D4, D5, D6, D7,
@@ -408,3 +449,31 @@ def : SubRegSet<6, [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7,
Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15],
[D1, D3, D5, D7, D9, D11, D13, D15,
D17, D19, D21, D23, D25, D27, D29, D31]>;
+
+// S sub-registers of QQ registers. Note there are no sub-indices
+// for referencing S4 - S7, S12 - S15, and S20 - S23. It doesn't
+// look like we need them.
+def : SubRegSet<1, [QQ0, QQ1, QQ2, QQ3],
+ [S0, S8, S16, S24]>;
+def : SubRegSet<2, [QQ0, QQ1, QQ2, QQ3],
+ [S1, S9, S17, S25]>;
+def : SubRegSet<3, [QQ0, QQ1, QQ2, QQ3],
+ [S2, S10, S18, S26]>;
+def : SubRegSet<4, [QQ0, QQ1, QQ2, QQ3],
+ [S3, S11, S19, S27]>;
+
+// D sub-registers of QQ registers.
+def : SubRegSet<5, [QQ0, QQ1, QQ2, QQ3, QQ4, QQ5, QQ6, QQ7],
+ [D0, D4, D8, D12, D16, D20, D24, D28]>;
+def : SubRegSet<6, [QQ0, QQ1, QQ2, QQ3, QQ4, QQ5, QQ6, QQ7],
+ [D1, D5, D9, D13, D17, D21, D25, D29]>;
+def : SubRegSet<7, [QQ0, QQ1, QQ2, QQ3, QQ4, QQ5, QQ6, QQ7],
+ [D2, D6, D10, D14, D18, D22, D26, D30]>;
+def : SubRegSet<8, [QQ0, QQ1, QQ2, QQ3, QQ4, QQ5, QQ6, QQ7],
+ [D3, D7, D11, D15, D19, D23, D27, D31]>;
+
+// Q sub-registers of QQ registers.
+def : SubRegSet<9, [QQ0, QQ1, QQ2, QQ3, QQ4, QQ5, QQ6, QQ7],
+ [Q0, Q2, Q4, Q6, Q8, Q10, Q12, Q14]>;
+def : SubRegSet<10,[QQ0, QQ1, QQ2, QQ3, QQ4, QQ5, QQ6, QQ7],
+ [Q1, Q3, Q5, Q7, Q9, Q11, Q13, Q15]>;
diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp
index 4f1c851632..f24138ae1d 100644
--- a/lib/Target/X86/X86RegisterInfo.cpp
+++ b/lib/Target/X86/X86RegisterInfo.cpp
@@ -716,7 +716,7 @@ static
void mergeSPUpdatesUp(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
unsigned StackPtr, uint64_t *NumBytes = NULL) {
if (MBBI == MBB.begin()) return;
-
+
MachineBasicBlock::iterator PI = prior(MBBI);
unsigned Opc = PI->getOpcode();
if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 ||
diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp
index d3bf60e1c8..dd0924f99c 100644
--- a/utils/TableGen/EDEmitter.cpp
+++ b/utils/TableGen/EDEmitter.cpp
@@ -575,10 +575,11 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
REG("s_cc_out");
REG("tGPR");
REG("DPR");
- REG("SPR");
- REG("QPR");
REG("DPR_VFP2");
REG("DPR_8");
+ REG("SPR");
+ REG("QPR");
+ REG("QQPR");
IMM("i32imm");
IMM("bf_inv_mask_imm");