diff --git a/llvm/lib/Target/ARM/ARMInstrNEON.td b/llvm/lib/Target/ARM/ARMInstrNEON.td index 8a706b1e4f0a6fe1b55b11b78fc1a02f564dd1e9..f61eb2b6355448e1fa0a021f62b8d32b2b894c14 100644 --- a/llvm/lib/Target/ARM/ARMInstrNEON.td +++ b/llvm/lib/Target/ARM/ARMInstrNEON.td @@ -163,14 +163,14 @@ def VecListDPairAllLanes : RegisterOperand { - 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 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 op7_4, string Dt> diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index fcb85449e63e5e9bf4079f9d9f9e3b70d177d6f3..fe93a4c612f2ea4dc3d6f1353b90793d4a550f5d 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -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 &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, diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 6fdc49d143b00e74c05b7101b4f68036c982a4dc..7ba714e96e022e2db52af64eb3b99cef392d5608 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -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; diff --git a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp index 8754053d62a19d3f0ec3b0d77d18d92bfb402705..2b994dfc4d46fb7d2700766f6c84a56d40402508 100644 --- a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp +++ b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp @@ -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. - 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, diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h index 06eb4e5078f45e53c71227ccd96978f5862b8877..ae11be888137d9cc50de8a5b4711f4842c9dc4d1 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h @@ -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 */ } } diff --git a/llvm/utils/TableGen/EDEmitter.cpp b/llvm/utils/TableGen/EDEmitter.cpp index b2912d0bb8b80b7febd0ec645df809dc5e6eb88d..1b473d37e7fa0f3d7447dc74d21e2aaf6c4e5ea0 100644 --- a/llvm/utils/TableGen/EDEmitter.cpp +++ b/llvm/utils/TableGen/EDEmitter.cpp @@ -580,7 +580,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, REG("VecListFourD"); REG("VecListOneDAllLanes"); REG("VecListDPairAllLanes"); - REG("VecListTwoQAllLanes"); + REG("VecListDPairSpacedAllLanes"); IMM("i32imm"); IMM("fbits16");