From b6310316dbaf8716003531d7ed245f77f1a76a11 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Fri, 21 Oct 2011 20:35:01 +0000 Subject: [PATCH] Assembly parsing for 4-register variant of VLD1. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142682 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMExpandPseudoInsts.cpp | 4 ++-- lib/Target/ARM/ARMInstrNEON.td | 17 +++++++++---- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 12 ++++++++++ .../ARM/Disassembler/ARMDisassembler.cpp | 24 ------------------- lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp | 11 +++++++++ lib/Target/ARM/InstPrinter/ARMInstPrinter.h | 1 + test/MC/ARM/neon-vld-encoding.s | 9 +++++++ utils/TableGen/EDEmitter.cpp | 1 + 8 files changed, 48 insertions(+), 31 deletions(-) diff --git a/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/lib/Target/ARM/ARMExpandPseudoInsts.cpp index a133f7ba0de..9cd689435b4 100644 --- a/lib/Target/ARM/ARMExpandPseudoInsts.cpp +++ b/lib/Target/ARM/ARMExpandPseudoInsts.cpp @@ -142,8 +142,8 @@ static const NEONLdStTableEntry NEONLdStTable[] = { { ARM::VLD1LNq8Pseudo, ARM::VLD1LNd8, true, false, EvenDblSpc, 1, 8 ,true}, { ARM::VLD1LNq8Pseudo_UPD, ARM::VLD1LNd8_UPD, true, true, EvenDblSpc, 1, 8 ,true}, -{ ARM::VLD1d64QPseudo, ARM::VLD1d64Q, true, false, SingleSpc, 4, 1 ,true}, -{ ARM::VLD1d64QPseudo_UPD, ARM::VLD1d64Q_UPD, true, true, SingleSpc, 4, 1 ,true}, +{ ARM::VLD1d64QPseudo, ARM::VLD1d64Q, true, false, SingleSpc, 4, 1 ,false}, +{ ARM::VLD1d64QPseudo_UPD, ARM::VLD1d64Q_UPD, true, true, SingleSpc, 4, 1 ,false}, { ARM::VLD1d64TPseudo, ARM::VLD1d64T, true, false, SingleSpc, 3, 1 ,false}, { ARM::VLD1d64TPseudo_UPD, ARM::VLD1d64T_UPD, true, true, SingleSpc, 3, 1 ,false}, diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td index f917bc0429d..78a57fb22a1 100644 --- a/lib/Target/ARM/ARMInstrNEON.td +++ b/lib/Target/ARM/ARMInstrNEON.td @@ -93,6 +93,14 @@ def VecListThreeDAsmOperand : AsmOperandClass { def VecListThreeD : RegisterOperand { let ParserMatchClass = VecListThreeDAsmOperand; } +// Register list of four sequential D registers. +def VecListFourDAsmOperand : AsmOperandClass { + let Name = "VecListFourD"; + let ParserMethod = "parseVectorList"; +} +def VecListFourD : RegisterOperand { + let ParserMatchClass = VecListFourDAsmOperand; +} //===----------------------------------------------------------------------===// // NEON-specific DAG Nodes. @@ -357,18 +365,17 @@ def VLD1d64TPseudo_UPD : VLDQQWBPseudo; // ...with 4 registers class VLD1D4 op7_4, string Dt> - : NLdSt<0,0b10,0b0010,op7_4,(outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4), + : NLdSt<0, 0b10, 0b0010, op7_4, (outs VecListFourD:$Vd), (ins addrmode6:$Rn), IIC_VLD1x4, "vld1", Dt, - "\\{$Vd, $dst2, $dst3, $dst4\\}, $Rn", "", []> { + "$Vd, $Rn", "", []> { let Rm = 0b1111; let Inst{5-4} = Rn{5-4}; let DecoderMethod = "DecodeVLDInstruction"; } class VLD1D4WB op7_4, string Dt> - : NLdSt<0,0b10,0b0010,op7_4, - (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, DPR:$dst4, GPR:$wb), + : NLdSt<0, 0b10, 0b0010, op7_4, (outs VecListFourD:$Vd, GPR:$wb), (ins addrmode6:$Rn, am6offset:$Rm), IIC_VLD1x4u, "vld1", Dt, - "\\{$Vd, $dst2, $dst3, $dst4\\}, $Rn$Rm", "$Rn.addr = $wb", + "$Vd, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{5-4} = Rn{5-4}; let DecoderMethod = "DecodeVLDInstruction"; diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 1db82681699..36438dbe12d 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -925,6 +925,11 @@ public: return VectorList.Count == 3; } + bool isVecListFourD() const { + if (Kind != k_VectorList) return false; + return VectorList.Count == 4; + } + bool isVectorIndex8() const { if (Kind != k_VectorIndex) return false; return VectorIndex.Val < 8; @@ -1531,6 +1536,13 @@ public: Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum)); } + void addVecListFourDOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + // Only the first register actually goes on the instruction. The rest + // are implied by the opcode. + Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum)); + } + void addVectorIndex8Operands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); Inst.addOperand(MCOperand::CreateImm(getVectorIndex())); diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 361cf91f012..577dd806c29 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -1959,14 +1959,6 @@ static DecodeStatus DecodeVLDInstruction(llvm::MCInst &Inst, unsigned Insn, // Second output register switch (Inst.getOpcode()) { - case ARM::VLD1d8Q: - case ARM::VLD1d16Q: - case ARM::VLD1d32Q: - case ARM::VLD1d64Q: - case ARM::VLD1d8Q_UPD: - case ARM::VLD1d16Q_UPD: - case ARM::VLD1d32Q_UPD: - case ARM::VLD1d64Q_UPD: case ARM::VLD2d8: case ARM::VLD2d16: case ARM::VLD2d32: @@ -2020,14 +2012,6 @@ static DecodeStatus DecodeVLDInstruction(llvm::MCInst &Inst, unsigned Insn, // Third output register switch(Inst.getOpcode()) { - case ARM::VLD1d8Q: - case ARM::VLD1d16Q: - case ARM::VLD1d32Q: - case ARM::VLD1d64Q: - case ARM::VLD1d8Q_UPD: - case ARM::VLD1d16Q_UPD: - case ARM::VLD1d32Q_UPD: - case ARM::VLD1d64Q_UPD: case ARM::VLD2q8: case ARM::VLD2q16: case ARM::VLD2q32: @@ -2070,14 +2054,6 @@ static DecodeStatus DecodeVLDInstruction(llvm::MCInst &Inst, unsigned Insn, // Fourth output register switch (Inst.getOpcode()) { - case ARM::VLD1d8Q: - case ARM::VLD1d16Q: - case ARM::VLD1d32Q: - case ARM::VLD1d64Q: - case ARM::VLD1d8Q_UPD: - case ARM::VLD1d16Q_UPD: - case ARM::VLD1d32Q_UPD: - case ARM::VLD1d64Q_UPD: case ARM::VLD2q8: case ARM::VLD2q16: case ARM::VLD2q32: diff --git a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp index df79603cb0f..e4a56be9e40 100644 --- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp +++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp @@ -1014,3 +1014,14 @@ void ARMInstPrinter::printVectorListThree(const MCInst *MI, unsigned OpNum, << getRegisterName(MI->getOperand(OpNum).getReg() + 1) << ", " << getRegisterName(MI->getOperand(OpNum).getReg() + 2) << "}"; } + +void ARMInstPrinter::printVectorListFour(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() + 1) << ", " + << getRegisterName(MI->getOperand(OpNum).getReg() + 2) << ", " + << getRegisterName(MI->getOperand(OpNum).getReg() + 3) << "}"; +} diff --git a/lib/Target/ARM/InstPrinter/ARMInstPrinter.h b/lib/Target/ARM/InstPrinter/ARMInstPrinter.h index 7157e7b4f3d..3f38f1a0ee2 100644 --- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.h +++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.h @@ -132,6 +132,7 @@ public: void printVectorListOne(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printVectorListTwo(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printVectorListThree(const MCInst *MI, unsigned OpNum, raw_ostream &O); + void printVectorListFour(const MCInst *MI, unsigned OpNum, raw_ostream &O); }; } // end namespace llvm diff --git a/test/MC/ARM/neon-vld-encoding.s b/test/MC/ARM/neon-vld-encoding.s index f2ad3ad6509..56cd7b3eb55 100644 --- a/test/MC/ARM/neon-vld-encoding.s +++ b/test/MC/ARM/neon-vld-encoding.s @@ -12,6 +12,10 @@ vld1.16 {d4, d5, d6}, [r3, :64] vld1.32 {d5, d6, d7}, [r3] vld1.64 {d6, d7, d8}, [r3, :64] + vld1.8 {d1, d2, d3, d4}, [r3] + vld1.16 {d4, d5, d6, d7}, [r3, :64] + vld1.32 {d5, d6, d7, d8}, [r3] + vld1.64 {d6, d7, d8, d9}, [r3, :64] @ CHECK: vld1.8 {d16}, [r0, :64] @ encoding: [0x1f,0x07,0x60,0xf4] @ CHECK: vld1.16 {d16}, [r0] @ encoding: [0x4f,0x07,0x60,0xf4] @@ -25,6 +29,11 @@ @ CHECK: vld1.16 {d4, d5, d6}, [r3, :64] @ encoding: [0x5f,0x46,0x23,0xf4] @ CHECK: vld1.32 {d5, d6, d7}, [r3] @ encoding: [0x8f,0x56,0x23,0xf4] @ CHECK: vld1.64 {d6, d7, d8}, [r3, :64] @ encoding: [0xdf,0x66,0x23,0xf4] +@ CHECK: vld1.8 {d1, d2, d3, d4}, [r3] @ encoding: [0x0f,0x12,0x23,0xf4] +@ CHECK: vld1.16 {d4, d5, d6, d7}, [r3, :64] @ encoding: [0x5f,0x42,0x23,0xf4] +@ CHECK: vld1.32 {d5, d6, d7, d8}, [r3] @ encoding: [0x8f,0x52,0x23,0xf4] +@ CHECK: vld1.64 {d6, d7, d8, d9}, [r3, :64] @ encoding: [0xdf,0x62,0x23,0xf4] + @ vld2.8 {d16, d17}, [r0, :64] @ vld2.16 {d16, d17}, [r0, :128] diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index a7cc7dc6757..e731f111968 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/utils/TableGen/EDEmitter.cpp @@ -574,6 +574,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, REG("VecListOneD"); REG("VecListTwoD"); REG("VecListThreeD"); + REG("VecListFourD"); IMM("i32imm"); IMM("i32imm_hilo16");