ARM more NEON VLD/VST composite physical register refactoring.
authorJim Grosbach <grosbach@apple.com>
Tue, 6 Mar 2012 23:10:38 +0000 (23:10 +0000)
committerJim Grosbach <grosbach@apple.com>
Tue, 6 Mar 2012 23:10:38 +0000 (23:10 +0000)
Register pair, all lanes subscripting.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@152157 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMInstrNEON.td
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
lib/Target/ARM/Disassembler/ARMDisassembler.cpp
lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h
utils/TableGen/EDEmitter.cpp

index 8a706b1e4f0a6fe1b55b11b78fc1a02f564dd1e9..f61eb2b6355448e1fa0a021f62b8d32b2b894c14 100644 (file)
@@ -163,14 +163,14 @@ def VecListDPairAllLanes : RegisterOperand<DPair,
   let ParserMatchClass = VecListDPairAllLanesAsmOperand;
 }
 // Register list of two D registers spaced by 2 (two sequential Q registers).
-def VecListTwoQAllLanesAsmOperand : AsmOperandClass {
-  let Name = "VecListTwoQAllLanes";
+def VecListDPairSpacedAllLanesAsmOperand : AsmOperandClass {
+  let Name = "VecListDPairSpacedAllLanes";
   let ParserMethod = "parseVectorList";
   let RenderMethod = "addVecListOperands";
 }
-def VecListTwoQAllLanes : RegisterOperand<DPR,
+def VecListDPairSpacedAllLanes : RegisterOperand<DPair,
                                          "printVectorListTwoSpacedAllLanes"> {
-  let ParserMatchClass = VecListTwoQAllLanesAsmOperand;
+  let ParserMatchClass = VecListDPairSpacedAllLanesAsmOperand;
 }
 // Register list of three D registers, with "all lanes" subscripting.
 def VecListThreeDAllLanesAsmOperand : AsmOperandClass {
@@ -1369,10 +1369,10 @@ def VLD2DUPd8  : VLD2DUP<{0,0,0,?}, "8",  VecListDPairAllLanes>;
 def VLD2DUPd16 : VLD2DUP<{0,1,0,?}, "16", VecListDPairAllLanes>;
 def VLD2DUPd32 : VLD2DUP<{1,0,0,?}, "32", VecListDPairAllLanes>;
 
-// ...with double-spaced registers (not used for codegen):
-def VLD2DUPd8x2  : VLD2DUP<{0,0,1,?}, "8",  VecListTwoQAllLanes>;
-def VLD2DUPd16x2 : VLD2DUP<{0,1,1,?}, "16", VecListTwoQAllLanes>;
-def VLD2DUPd32x2 : VLD2DUP<{1,0,1,?}, "32", VecListTwoQAllLanes>;
+// ...with double-spaced registers
+def VLD2DUPd8x2  : VLD2DUP<{0,0,1,?}, "8",  VecListDPairSpacedAllLanes>;
+def VLD2DUPd16x2 : VLD2DUP<{0,1,1,?}, "16", VecListDPairSpacedAllLanes>;
+def VLD2DUPd32x2 : VLD2DUP<{1,0,1,?}, "32", VecListDPairSpacedAllLanes>;
 
 // ...with address register writeback:
 multiclass VLD2DUPWB<bits<4> op7_4, string Dt, RegisterOperand VdTy> {
@@ -1401,9 +1401,9 @@ defm VLD2DUPd8wb    : VLD2DUPWB<{0,0,0,0}, "8",  VecListDPairAllLanes>;
 defm VLD2DUPd16wb   : VLD2DUPWB<{0,1,0,?}, "16", VecListDPairAllLanes>;
 defm VLD2DUPd32wb   : VLD2DUPWB<{1,0,0,?}, "32", VecListDPairAllLanes>;
 
-defm VLD2DUPd8x2wb  : VLD2DUPWB<{0,0,1,0}, "8",  VecListTwoQAllLanes>;
-defm VLD2DUPd16x2wb : VLD2DUPWB<{0,1,1,?}, "16", VecListTwoQAllLanes>;
-defm VLD2DUPd32x2wb : VLD2DUPWB<{1,0,1,?}, "32", VecListTwoQAllLanes>;
+defm VLD2DUPd8x2wb  : VLD2DUPWB<{0,0,1,0}, "8",  VecListDPairSpacedAllLanes>;
+defm VLD2DUPd16x2wb : VLD2DUPWB<{0,1,1,?}, "16", VecListDPairSpacedAllLanes>;
+defm VLD2DUPd32x2wb : VLD2DUPWB<{1,0,1,?}, "32", VecListDPairSpacedAllLanes>;
 
 //   VLD3DUP  : Vector Load (single 3-element structure to all lanes)
 class VLD3DUP<bits<4> op7_4, string Dt>
index fcb85449e63e5e9bf4079f9d9f9e3b70d177d6f3..fe93a4c612f2ea4dc3d6f1353b90793d4a550f5d 100644 (file)
@@ -1101,11 +1101,6 @@ public:
     return VectorList.Count == 4;
   }
 
-  bool isVecListTwoQ() const {
-    if (!isDoubleSpacedVectorList()) return false;
-    return VectorList.Count == 2;
-  }
-
   bool isVecListDPairSpaced() const {
     if (!isSingleSpacedVectorList()) return false;
     return (ARMMCRegisterClasses[ARM::DPairSpcRegClassID]
@@ -1139,7 +1134,7 @@ public:
               .contains(VectorList.RegNum));
   }
 
-  bool isVecListTwoQAllLanes() const {
+  bool isVecListDPairSpacedAllLanes() const {
     if (!isDoubleSpacedVectorAllLanes()) return false;
     return VectorList.Count == 2;
   }
@@ -3169,8 +3164,10 @@ parseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
   case AllLanes:
     // Two-register operands have been converted to the
     // composite register classes.
-    if (Count == 2 && Spacing == 1) {
-      const MCRegisterClass *RC = &ARMMCRegisterClasses[ARM::DPairRegClassID];
+    if (Count == 2) {
+      const MCRegisterClass *RC = (Spacing == 1) ?
+        &ARMMCRegisterClasses[ARM::DPairRegClassID] :
+        &ARMMCRegisterClasses[ARM::DPairSpcRegClassID];
       FirstReg = MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC);
     }
     Operands.push_back(ARMOperand::CreateVectorListAllLanes(FirstReg, Count,
index 6fdc49d143b00e74c05b7101b4f68036c982a4dc..7ba714e96e022e2db52af64eb3b99cef392d5608 100644 (file)
@@ -2572,6 +2572,13 @@ static DecodeStatus DecodeVLD2DupInstruction(llvm::MCInst &Inst, unsigned Insn,
     if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
       return MCDisassembler::Fail;
     break;
+  case ARM::VLD2DUPd16x2: case ARM::VLD2DUPd32x2: case ARM::VLD2DUPd8x2:
+  case ARM::VLD2DUPd16x2wb_fixed: case ARM::VLD2DUPd16x2wb_register:
+  case ARM::VLD2DUPd32x2wb_fixed: case ARM::VLD2DUPd32x2wb_register:
+  case ARM::VLD2DUPd8x2wb_fixed: case ARM::VLD2DUPd8x2wb_register:
+    if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
+      return MCDisassembler::Fail;
+    break;
   default:
     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
       return MCDisassembler::Fail;
index 8754053d62a19d3f0ec3b0d77d18d92bfb402705..2b994dfc4d46fb7d2700766f6c84a56d40402508 100644 (file)
@@ -1104,11 +1104,10 @@ void ARMInstPrinter::printVectorListFourAllLanes(const MCInst *MI,
 void ARMInstPrinter::printVectorListTwoSpacedAllLanes(const MCInst *MI,
                                                       unsigned OpNum,
                                                       raw_ostream &O) {
-  // Normally, it's not safe to use register enum values directly with
-  // addition to get the next register, but for VFP registers, the
-  // sort order is guaranteed because they're all of the form D<n>.
-  O << "{" << getRegisterName(MI->getOperand(OpNum).getReg()) << "[], "
-    << getRegisterName(MI->getOperand(OpNum).getReg() + 2) << "[]}";
+  unsigned Reg = MI->getOperand(OpNum).getReg();
+  unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
+  unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
+  O << "{" << getRegisterName(Reg0) << "[], " << getRegisterName(Reg1) << "[]}";
 }
 
 void ARMInstPrinter::printVectorListThreeSpacedAllLanes(const MCInst *MI,
index 06eb4e5078f45e53c71227ccd96978f5862b8877..ae11be888137d9cc50de8a5b4711f4842c9dc4d1 100644 (file)
@@ -187,21 +187,37 @@ inline static unsigned getARMRegisterNumbering(unsigned Reg) {
   case S31: case D31: return 31;
 
   // Composite registers use the regnum of the first register in the list.
-  case D1_D2:   return 1;
-  case D3_D5:   return 3;
-  case D5_D7:   return 5;
-  case D7_D9:   return 7;
-  case D9_D10:  return 9;
-  case D11_D12: return 11;
-  case D13_D14: return 13;
-  case D15_D16: return 15;
-  case D17_D18: return 17;
-  case D19_D20: return 19;
-  case D21_D22: return 21;
-  case D23_D24: return 23;
-  case D25_D26: return 25;
-  case D27_D28: return 27;
-  case D29_D30: return 29;
+  /* Q0  */     case D0_D2:   return 0;
+  case D1_D2:   case D1_D3:   return 1;
+  /* Q1  */     case D2_D4:   return 2;
+  case D3_D4:   case D3_D5:   return 3;
+  /* Q2  */     case D4_D6:   return 4;
+  case D5_D6:   case D5_D7:   return 5;
+  /* Q3  */     case D6_D8:   return 6;
+  case D7_D8:   case D7_D9:   return 7;
+  /* Q4  */     case D8_D10:  return 8;
+  case D9_D10:  case D9_D11:  return 9;
+  /* Q5  */     case D10_D12: return 10;
+  case D11_D12: case D11_D13: return 11;
+  /* Q6  */     case D12_D14: return 12;
+  case D13_D14: case D13_D15: return 13;
+  /* Q7  */     case D14_D16: return 14;
+  case D15_D16: case D15_D17: return 15;
+  /* Q8  */     case D16_D18: return 16;
+  case D17_D18: case D17_D19: return 17;
+  /* Q9  */     case D18_D20: return 18;
+  case D19_D20: case D19_D21: return 19;
+  /* Q10 */     case D20_D22: return 20;
+  case D21_D22: case D21_D23: return 21;
+  /* Q11 */     case D22_D24: return 22;
+  case D23_D24: case D23_D25: return 23;
+  /* Q12 */     case D24_D26: return 24;
+  case D25_D26: case D25_D27: return 25;
+  /* Q13 */     case D26_D28: return 26;
+  case D27_D28: case D27_D29: return 27;
+  /* Q14 */     case D28_D30: return 28;
+  case D29_D30: case D29_D31: return 29;
+  /* Q15 */
   }
 }
 
index b2912d0bb8b80b7febd0ec645df809dc5e6eb88d..1b473d37e7fa0f3d7447dc74d21e2aaf6c4e5ea0 100644 (file)
@@ -580,7 +580,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
   REG("VecListFourD");
   REG("VecListOneDAllLanes");
   REG("VecListDPairAllLanes");
-  REG("VecListTwoQAllLanes");
+  REG("VecListDPairSpacedAllLanes");
 
   IMM("i32imm");
   IMM("fbits16");