Added a QQQQ register file to model 4-consecutive Q registers.
authorEvan Cheng <evan.cheng@apple.com>
Fri, 14 May 2010 02:13:41 +0000 (02:13 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Fri, 14 May 2010 02:13:41 +0000 (02:13 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103760 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMBaseInstrInfo.cpp
lib/Target/ARM/ARMBaseRegisterInfo.cpp
lib/Target/ARM/ARMISelLowering.cpp
lib/Target/ARM/ARMInstrNEON.td
lib/Target/ARM/ARMRegisterInfo.h
lib/Target/ARM/ARMRegisterInfo.td
utils/TableGen/EDEmitter.cpp

index 524b5443382d2a176682cbd56c5d22c811dc4775..b2f67d8a51e7c83f2c033459b14df045c235ca3d 100644 (file)
@@ -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;
 }
 
index dd6204996dc6f1f974bda21391036d511b63c346..1f7d8420cbdff7f142c3ff938cf6b0effd4a3518 100644 (file)
@@ -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;
index a0d88e11a04c9168203e83f48b9e729cb2920c10..529f7115f5b19216d005cad70cc9bd34d5bf2c56 100644 (file)
@@ -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.
index 385a50bd4db8145b514e5ad3f651e073d4e157c4..ef0d181fb0075f6ef46897df8da3305d4acc49d4 100644 (file)
@@ -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)
index f13c7d4acceb7ca3a3642aebafb8b0b4e58bd234..efc0cbb0651add9ef7b7d080e68d3ac5e0963fd6 100644 (file)
@@ -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
   };
 }
 
index 7e17caa0986c99dd43d78a075db1a8c0838849c0..ae2b95bef60dd2a0bff6820f6d2f795aedb648b6 100644 (file)
@@ -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]>;
index 406c48a5e5ef99687cfae82b1b6222586c855fdf..0d5ee40aaaa9924084c6d0b35de1253d14daf5cb 100644 (file)
@@ -579,6 +579,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
   REG("SPR");
   REG("QPR");
   REG("QQPR");
+  REG("QQQQPR");
   
   IMM("i32imm");
   IMM("bf_inv_mask_imm");