From b63387afc6b10e88631d1ef232c41ab6c18c8581 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Thu, 6 May 2010 06:36:08 +0000 Subject: [PATCH] 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 --- lib/Target/ARM/ARMBaseInstrInfo.cpp | 51 +++++++++++++------ lib/Target/ARM/ARMBaseRegisterInfo.cpp | 41 ++++++++++++--- lib/Target/ARM/ARMInstrNEON.td | 5 ++ lib/Target/ARM/ARMRegisterInfo.h | 3 +- lib/Target/ARM/ARMRegisterInfo.td | 69 ++++++++++++++++++++++++++ lib/Target/X86/X86RegisterInfo.cpp | 2 +- utils/TableGen/EDEmitter.cpp | 5 +- 7 files changed, 150 insertions(+), 26 deletions(-) diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 0cf85e86afb..d886a1f81bb 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 bc121874368..bf779ccf554 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 d5ce2b8468d..9577e0bffc9 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 041afd04140..f13c7d4acce 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 0d4200c63d5..29907caa3f9 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 4f1c851632e..f24138ae1de 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 d3bf60e1c8c..dd0924f99cb 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"); -- 2.34.1