From 22c687b6421d9cc03351ddb0c7fd3d45382bc01a Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Fri, 14 May 2010 02:13:41 +0000 Subject: [PATCH] Added a QQQQ register file to model 4-consecutive Q registers. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103760 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMBaseInstrInfo.cpp | 54 +++++++++---- lib/Target/ARM/ARMBaseRegisterInfo.cpp | 67 ++++++++++++---- lib/Target/ARM/ARMISelLowering.cpp | 4 +- lib/Target/ARM/ARMInstrNEON.td | 5 +- lib/Target/ARM/ARMRegisterInfo.h | 7 +- lib/Target/ARM/ARMRegisterInfo.td | 104 +++++++++++++++++++++---- utils/TableGen/EDEmitter.cpp | 1 + 7 files changed, 190 insertions(+), 52 deletions(-) diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 524b5443382..b2f67d8a51e 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -680,12 +680,10 @@ 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) + // Allow QQPR / QQPR_VFP2 cross-class copies. + if (DestRC == ARM::QQPR_VFP2RegisterClass) DestRC = ARM::QQPRRegisterClass; - if (SrcRC == ARM::QQPR_VFP2RegisterClass || - SrcRC == ARM::QQPR_8RegisterClass) + if (SrcRC == ARM::QQPR_VFP2RegisterClass) SrcRC = ARM::QQPRRegisterClass; // Disallow copies of unequal sizes. @@ -714,6 +712,8 @@ ARMBaseInstrInfo::copyRegToReg(MachineBasicBlock &MBB, Opc = ARM::VMOVQ; else if (DestRC == ARM::QQPRRegisterClass) Opc = ARM::VMOVQQ; + else if (DestRC == ARM::QQQQPRRegisterClass) + Opc = ARM::VMOVQQQQ; else return false; @@ -787,11 +787,10 @@ 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!"); + } else if (RC == ARM::QQPRRegisterClass || RC == ARM::QQPR_VFP2RegisterClass){ if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) { + // FIXME: It's possible to only store part of the QQ register if the + // spilled def has a sub-register index. MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::VST2q32)) .addFrameIndex(FI).addImm(128); MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_0, getKillRegState(isKill), TRI); @@ -810,6 +809,21 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_2, 0, TRI); AddDReg(MIB, SrcReg, ARM::DSUBREG_3, 0, TRI); } + } else { + assert(RC == ARM::QQQQPRRegisterClass && "Unknown regclass!"); + MachineInstrBuilder MIB = + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTMD)) + .addFrameIndex(FI) + .addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4))) + .addMemOperand(MMO); + MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_0, getKillRegState(isKill), TRI); + MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_1, 0, TRI); + MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_2, 0, TRI); + MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_3, 0, TRI); + MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_4, 0, TRI); + MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_5, 0, TRI); + MIB = AddDReg(MIB, SrcReg, ARM::DSUBREG_6, 0, TRI); + AddDReg(MIB, SrcReg, ARM::DSUBREG_7, 0, TRI); } } @@ -858,10 +872,7 @@ 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!"); + } else if (RC == ARM::QQPRRegisterClass || RC == ARM::QQPR_VFP2RegisterClass){ if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) { MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::VLD2q32)); MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_0, RegState::Define, TRI); @@ -880,6 +891,21 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_2, RegState::Define, TRI); AddDReg(MIB, DestReg, ARM::DSUBREG_3, RegState::Define, TRI); } + } else { + assert(RC == ARM::QQQQPRRegisterClass && "Unknown regclass!"); + MachineInstrBuilder MIB = + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDMD)) + .addFrameIndex(FI) + .addImm(ARM_AM::getAM5Opc(ARM_AM::ia, 4))) + .addMemOperand(MMO); + MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_0, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_1, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_2, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_3, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_4, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_5, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::DSUBREG_6, RegState::Define, TRI); + AddDReg(MIB, DestReg, ARM::DSUBREG_7, RegState::Define, TRI); } } @@ -1105,6 +1131,8 @@ ARMBaseInstrInfo::canFoldMemoryOperand(const MachineInstr *MI, return true; } + // FIXME: VMOVQQ and VMOVQQQQ? + return false; } diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp index dd6204996dc..1f7d8420cbd 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -279,10 +279,14 @@ ARMBaseRegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A, return &ARM::QPR_VFP2RegClass; } - assert(A->getSize() == 32 && "Expecting a QQ register class!"); - if (B == &ARM::SPR_8RegClass) - return &ARM::QQPR_8RegClass; - return &ARM::QQPR_VFP2RegClass; + if (A->getSize() == 32) { + if (B == &ARM::SPR_8RegClass) + return 0; // Do not allow coalescing! + return &ARM::QQPR_VFP2RegClass; + } + + assert(A->getSize() == 64 && "Expecting a QQQQ register class!"); + return 0; // Do not allow coalescing! } case 5: case 6: @@ -293,26 +297,55 @@ ARMBaseRegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A, if (B == &ARM::DPR_VFP2RegClass) return &ARM::QPR_VFP2RegClass; if (B == &ARM::DPR_8RegClass) - return &ARM::QPR_8RegClass; + return 0; // Do not allow coalescing! return A; } - assert(A->getSize() == 32 && "Expecting a QQ register class!"); - if (B == &ARM::DPR_VFP2RegClass) - return &ARM::QQPR_VFP2RegClass; - if (B == &ARM::DPR_8RegClass) - return &ARM::QQPR_8RegClass; + if (A->getSize() == 32) { + if (B == &ARM::DPR_VFP2RegClass) + return &ARM::QQPR_VFP2RegClass; + if (B == &ARM::DPR_8RegClass) + return 0; // Do not allow coalescing! + return A; + } + + assert(A->getSize() == 64 && "Expecting a QQQQ register class!"); + if (B != &ARM::DPRRegClass) + return 0; // Do not allow coalescing! return A; } case 9: - case 10: { + case 10: + case 11: + case 12: { + // D sub-registers of QQQQ registers. + if (A->getSize() == 64 && B == &ARM::DPRRegClass) + return A; + return 0; // Do not allow coalescing! + } + + case 13: + case 14: { // 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; + if (A->getSize() == 32) { + if (B == &ARM::QPR_VFP2RegClass) + return &ARM::QQPR_VFP2RegClass; + if (B == &ARM::QPR_8RegClass) + return 0; // Do not allow coalescing! + return A; + } + + assert(A->getSize() == 64 && "Expecting a QQQQ register class!"); + if (B == &ARM::QPRRegClass) + return A; + return 0; // Do not allow coalescing! + } + case 15: + case 16: { + // Q sub-registers of QQQQ registers. + if (A->getSize() == 64 && B == &ARM::QPRRegClass) + return A; + return 0; // Do not allow coalescing! } } return 0; diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index a0d88e11a04..529f7115f5b 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -267,9 +267,11 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) addQRTypeForNEON(MVT::v2i64); // Map v4i64 to QQ registers but do not make the type legal for any - // operations. v4i64 is only used for REG_SEQUENCE to load / store quad + // operations. Similarly map v8i64 to QQQQ registers. v4i64 and v8i64 are + // only used for REG_SEQUENCE to load / store 4 to 8 consecutive // D registers. addRegisterClass(MVT::v4i64, ARM::QQPRRegisterClass); + addRegisterClass(MVT::v8i64, ARM::QQQQPRRegisterClass); // v2f64 is legal so that QR subregs can be extracted as f64 elements, but // neither Neon nor VFP support any arithmetic operations on it. diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td index 385a50bd4db..ef0d181fb00 100644 --- a/lib/Target/ARM/ARMInstrNEON.td +++ b/lib/Target/ARM/ARMInstrNEON.td @@ -2816,10 +2816,13 @@ 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 +// Pseudo vector move instructions for QQ and QQQQ registers. This should // be expanded after register allocation is completed. def VMOVQQ : PseudoInst<(outs QQPR:$dst), (ins QQPR:$src), NoItinerary, "@ vmov\t$dst, $src", []>; + +def VMOVQQQQ : PseudoInst<(outs QQQQPR:$dst), (ins QQQQPR:$src), + NoItinerary, "@ vmov\t$dst, $src", []>; } // neverHasSideEffects // VMOV : Vector Move (Immediate) diff --git a/lib/Target/ARM/ARMRegisterInfo.h b/lib/Target/ARM/ARMRegisterInfo.h index f13c7d4acce..efc0cbb0651 100644 --- a/lib/Target/ARM/ARMRegisterInfo.h +++ b/lib/Target/ARM/ARMRegisterInfo.h @@ -28,9 +28,10 @@ namespace ARM { /// these indices must be kept in sync with the class indices in the /// ARMRegisterInfo.td file. enum SubregIndex { - SSUBREG_0 = 1, SSUBREG_1 = 2, SSUBREG_2 = 3, SSUBREG_3 = 4, - DSUBREG_0 = 5, DSUBREG_1 = 6, DSUBREG_2 = 7, DSUBREG_3 = 8, - QSUBREG_0 = 9, QSUBREG_1 = 10 + SSUBREG_0 = 1, SSUBREG_1 = 2, SSUBREG_2 = 3, SSUBREG_3 = 4, + DSUBREG_0 = 5, DSUBREG_1 = 6, DSUBREG_2 = 7, DSUBREG_3 = 8, + DSUBREG_4 = 9, DSUBREG_5 = 10, DSUBREG_6 = 11, DSUBREG_7 = 12, + QSUBREG_0 = 13, QSUBREG_1 = 14, QSUBREG_2 = 15, QSUBREG_3 = 16 }; } diff --git a/lib/Target/ARM/ARMRegisterInfo.td b/lib/Target/ARM/ARMRegisterInfo.td index 7e17caa0986..ae2b95bef60 100644 --- a/lib/Target/ARM/ARMRegisterInfo.td +++ b/lib/Target/ARM/ARMRegisterInfo.td @@ -87,6 +87,7 @@ def D24 : ARMFReg<24, "d24">; def D25 : ARMFReg<25, "d25">; def D26 : ARMFReg<26, "d26">; def D27 : ARMFReg<27, "d27">; def D28 : ARMFReg<28, "d28">; def D29 : ARMFReg<29, "d29">; def D30 : ARMFReg<30, "d30">; def D31 : ARMFReg<31, "d31">; +def DDummy : ARMFReg<31, "dINVALID">; // Advanced SIMD (NEON) defines 16 quad-word aliases def Q0 : ARMReg< 0, "q0", [D0, D1]>; @@ -105,6 +106,7 @@ def Q12 : ARMReg<12, "q12", [D24, D25]>; def Q13 : ARMReg<13, "q13", [D26, D27]>; def Q14 : ARMReg<14, "q14", [D28, D29]>; def Q15 : ARMReg<15, "q15", [D30, D31]>; +def QDummy : ARMFReg<16, "qINVALID">; // Pseudo 256-bit registers to represent pairs of Q registers. These should // never be present in the emitted code. @@ -122,6 +124,12 @@ def QQ5 : ARMReg<5, "qq5", [Q10, Q11]>; def QQ6 : ARMReg<6, "qq6", [Q12, Q13]>; def QQ7 : ARMReg<7, "qq7", [Q14, Q15]>; +// Pseudo 512-bit registers to represent four consecutive Q registers. +def QQQQ0 : ARMReg<0, "qqqq0", [QQ0, QQ1]>; +def QQQQ1 : ARMReg<1, "qqqq1", [QQ2, QQ3]>; +def QQQQ2 : ARMReg<2, "qqqq2", [QQ4, QQ5]>; +def QQQQ3 : ARMReg<3, "qqqq3", [QQ6, QQ7]>; + // Current Program Status Register. def CPSR : ARMReg<0, "cpsr">; @@ -358,34 +366,56 @@ def DPR_8 : RegisterClass<"ARM", [f64, v8i8, v4i16, v2i32, v1i64, v2f32], 64, let SubRegClassList = [SPR_8, SPR_8]; } +// Dummy 64-bit regclass to represent impossible subreg indices. +def DPR_INVALID : RegisterClass<"ARM", + [f64, v8i8, v4i16, v2i32, v1i64, v2f32], 64, + [DDummy]> { + let CopyCost = -1; +} + // Generic 128-bit vector register class. def QPR : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], 128, [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15]> { let SubRegClassList = [SPR_INVALID, SPR_INVALID, SPR_INVALID, SPR_INVALID, - DPR, DPR]; + DPR, DPR, DPR_INVALID, DPR_INVALID, + DPR_INVALID, DPR_INVALID, DPR_INVALID, DPR_INVALID]; } // Subset of QPR that have 32-bit SPR subregs. def QPR_VFP2 : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], 128, [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]> { - let SubRegClassList = [SPR, SPR, SPR, SPR, DPR_VFP2, DPR_VFP2]; + let SubRegClassList = [SPR, SPR, SPR, SPR, + DPR_VFP2, DPR_VFP2, DPR_INVALID, DPR_INVALID, + DPR_INVALID, DPR_INVALID, DPR_INVALID, DPR_INVALID]; } // Subset of QPR that have DPR_8 and SPR_8 subregs. def QPR_8 : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], 128, [Q0, Q1, Q2, Q3]> { - let SubRegClassList = [SPR_8, SPR_8, SPR_8, SPR_8, DPR_8, DPR_8]; + let SubRegClassList = [SPR_8, SPR_8, SPR_8, SPR_8, + DPR_8, DPR_8, DPR_INVALID, DPR_INVALID, + DPR_INVALID, DPR_INVALID, DPR_INVALID, DPR_INVALID]; +} + +// Dummy 128-bit regclass to represent impossible subreg indices. +def QPR_INVALID : RegisterClass<"ARM", + [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], 128, + [QDummy]> { + let CopyCost = -1; } -// Pseudo 256-bit vector register class to model pairs of Q registers. +// Pseudo 256-bit vector register class to model pairs of Q registers +// (4 consecutive D 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]; + DPR, DPR, DPR, DPR, + DPR_INVALID, DPR_INVALID, DPR_INVALID, DPR_INVALID, + QPR, QPR, QPR_INVALID, QPR_INVALID]; } // Subset of QQPR that have 32-bit SPR subregs. @@ -394,16 +424,18 @@ def QQPR_VFP2 : RegisterClass<"ARM", [v4i64], [QQ0, QQ1, QQ2, QQ3]> { let SubRegClassList = [SPR, SPR, SPR, SPR, DPR_VFP2, DPR_VFP2, DPR_VFP2, DPR_VFP2, - QPR_VFP2, QPR_VFP2]; + DPR_INVALID, DPR_INVALID, DPR_INVALID, DPR_INVALID, + QPR_VFP2, QPR_VFP2, QPR_INVALID, QPR_INVALID]; } -// 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]; +// Pseudo 512-bit vector register class to model 4 consecutive Q registers +// (8 consecutive D registers). +def QQQQPR : RegisterClass<"ARM", [v8i64], + 256, + [QQQQ0, QQQQ1, QQQQ2, QQQQ3]> { + let SubRegClassList = [SPR_INVALID, SPR_INVALID, SPR_INVALID, SPR_INVALID, + DPR, DPR, DPR, DPR, DPR, DPR, DPR, DPR, + QPR, QPR, QPR, QPR]; } // Condition code registers. @@ -418,12 +450,20 @@ def arm_ssubreg_0 : PatLeaf<(i32 1)>; def arm_ssubreg_1 : PatLeaf<(i32 2)>; 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)>; +def arm_dsubreg_4 : PatLeaf<(i32 9)>; +def arm_dsubreg_5 : PatLeaf<(i32 10)>; +def arm_dsubreg_6 : PatLeaf<(i32 11)>; +def arm_dsubreg_7 : PatLeaf<(i32 12)>; + +def arm_qsubreg_0 : PatLeaf<(i32 13)>; +def arm_qsubreg_1 : PatLeaf<(i32 14)>; +def arm_qsubreg_2 : PatLeaf<(i32 15)>; +def arm_qsubreg_3 : PatLeaf<(i32 16)>; // S sub-registers of D registers. def : SubRegSet<1, [D0, D1, D2, D3, D4, D5, D6, D7, @@ -478,7 +518,37 @@ 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], +def : SubRegSet<13, [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], +def : SubRegSet<14,[QQ0, QQ1, QQ2, QQ3, QQ4, QQ5, QQ6, QQ7], [Q1, Q3, Q5, Q7, Q9, Q11, Q13, Q15]>; + + +// D sub-registers of QQQQ registers. +def : SubRegSet<5, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], + [D0, D8, D16, D24]>; +def : SubRegSet<6, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], + [D1, D9, D17, D25]>; +def : SubRegSet<7, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], + [D2, D10, D18, D26]>; +def : SubRegSet<8, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], + [D3, D11, D19, D27]>; + +def : SubRegSet<9, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], + [D4, D12, D20, D28]>; +def : SubRegSet<10, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], + [D5, D13, D21, D29]>; +def : SubRegSet<11, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], + [D6, D14, D22, D30]>; +def : SubRegSet<12, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], + [D7, D15, D23, D31]>; + +// Q sub-registers of QQQQQQQQ registers. +def : SubRegSet<13, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], + [Q0, Q4, Q8, Q12]>; +def : SubRegSet<14, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], + [Q1, Q5, Q9, Q13]>; +def : SubRegSet<15, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], + [Q2, Q6, Q10, Q14]>; +def : SubRegSet<16, [QQQQ0, QQQQ1, QQQQ2, QQQQ3], + [Q3, Q7, Q11, Q15]>; diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index 406c48a5e5e..0d5ee40aaaa 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/utils/TableGen/EDEmitter.cpp @@ -579,6 +579,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, REG("SPR"); REG("QPR"); REG("QQPR"); + REG("QQQQPR"); IMM("i32imm"); IMM("bf_inv_mask_imm"); -- 2.34.1