From e90ac9bce9aa6de288568df9bf6133c08534ae2f Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Wed, 14 Dec 2011 19:35:22 +0000 Subject: [PATCH] ARM NEON VST2 assembly parsing and encoding. Work in progress. Parsing for non-writeback, single spaced register lists works now. The rest have the representations better factored, but still need more to be able to parse properly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146579 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMExpandPseudoInsts.cpp | 26 ++++---- lib/Target/ARM/ARMInstrNEON.td | 60 +++++++++---------- .../ARM/Disassembler/ARMDisassembler.cpp | 30 ---------- lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp | 10 ++++ lib/Target/ARM/InstPrinter/ARMInstPrinter.h | 2 + test/MC/ARM/neon-vst-encoding.s | 26 ++++---- test/MC/Disassembler/ARM/neont2.txt | 2 +- 7 files changed, 66 insertions(+), 90 deletions(-) diff --git a/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/lib/Target/ARM/ARMExpandPseudoInsts.cpp index 089283c2af9..69011d73caf 100644 --- a/lib/Target/ARM/ARMExpandPseudoInsts.cpp +++ b/lib/Target/ARM/ARMExpandPseudoInsts.cpp @@ -307,19 +307,19 @@ static const NEONLdStTableEntry NEONLdStTable[] = { { ARM::VST2LNq32Pseudo, ARM::VST2LNq32, false, false, false, EvenDblSpc, 2, 2,true}, { ARM::VST2LNq32Pseudo_UPD, ARM::VST2LNq32_UPD, false, true, true, EvenDblSpc, 2, 2,true}, -{ ARM::VST2d16Pseudo, ARM::VST2d16, false, false, false, SingleSpc, 2, 4 ,true}, -{ ARM::VST2d16Pseudo_UPD, ARM::VST2d16_UPD, false, true, true, SingleSpc, 2, 4 ,true}, -{ ARM::VST2d32Pseudo, ARM::VST2d32, false, false, false, SingleSpc, 2, 2 ,true}, -{ ARM::VST2d32Pseudo_UPD, ARM::VST2d32_UPD, false, true, true, SingleSpc, 2, 2 ,true}, -{ ARM::VST2d8Pseudo, ARM::VST2d8, false, false, false, SingleSpc, 2, 8 ,true}, -{ ARM::VST2d8Pseudo_UPD, ARM::VST2d8_UPD, false, true, true, SingleSpc, 2, 8 ,true}, - -{ ARM::VST2q16Pseudo, ARM::VST2q16, false, false, false, SingleSpc, 4, 4 ,true}, -{ ARM::VST2q16Pseudo_UPD, ARM::VST2q16_UPD, false, true, true, SingleSpc, 4, 4 ,true}, -{ ARM::VST2q32Pseudo, ARM::VST2q32, false, false, false, SingleSpc, 4, 2 ,true}, -{ ARM::VST2q32Pseudo_UPD, ARM::VST2q32_UPD, false, true, true, SingleSpc, 4, 2 ,true}, -{ ARM::VST2q8Pseudo, ARM::VST2q8, false, false, false, SingleSpc, 4, 8 ,true}, -{ ARM::VST2q8Pseudo_UPD, ARM::VST2q8_UPD, false, true, true, SingleSpc, 4, 8 ,true}, +{ ARM::VST2d16Pseudo, ARM::VST2d16, false, false, false, SingleSpc, 2, 4 ,false}, +{ ARM::VST2d16Pseudo_UPD, ARM::VST2d16_UPD, false, true, true, SingleSpc, 2, 4 ,false}, +{ ARM::VST2d32Pseudo, ARM::VST2d32, false, false, false, SingleSpc, 2, 2 ,false}, +{ ARM::VST2d32Pseudo_UPD, ARM::VST2d32_UPD, false, true, true, SingleSpc, 2, 2 ,false}, +{ ARM::VST2d8Pseudo, ARM::VST2d8, false, false, false, SingleSpc, 2, 8 ,false}, +{ ARM::VST2d8Pseudo_UPD, ARM::VST2d8_UPD, false, true, true, SingleSpc, 2, 8 ,false}, + +{ ARM::VST2q16Pseudo, ARM::VST2q16, false, false, false, SingleSpc, 4, 4 ,false}, +{ ARM::VST2q16Pseudo_UPD, ARM::VST2q16_UPD, false, true, true, SingleSpc, 4, 4 ,false}, +{ ARM::VST2q32Pseudo, ARM::VST2q32, false, false, false, SingleSpc, 4, 2 ,false}, +{ ARM::VST2q32Pseudo_UPD, ARM::VST2q32_UPD, false, true, true, SingleSpc, 4, 2 ,false}, +{ ARM::VST2q8Pseudo, ARM::VST2q8, false, false, false, SingleSpc, 4, 8 ,false}, +{ ARM::VST2q8Pseudo_UPD, ARM::VST2q8_UPD, false, true, true, SingleSpc, 4, 8 ,false}, { ARM::VST3LNd16Pseudo, ARM::VST3LNd16, false, false, false, SingleSpc, 3, 4 ,true}, { ARM::VST3LNd16Pseudo_UPD, ARM::VST3LNd16_UPD, false, true, true, SingleSpc, 3, 4 ,true}, diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td index 58fc0190322..a03195d05f3 100644 --- a/lib/Target/ARM/ARMInstrNEON.td +++ b/lib/Target/ARM/ARMInstrNEON.td @@ -116,7 +116,7 @@ def VecListTwoQAsmOperand : AsmOperandClass { let ParserMethod = "parseVectorList"; let RenderMethod = "addVecListOperands"; } -def VecListTwoQ : RegisterOperand { +def VecListTwoQ : RegisterOperand { let ParserMatchClass = VecListTwoQAsmOperand; } @@ -1497,31 +1497,28 @@ def VST1d64QPseudoWB_fixed : VSTQQWBPseudo; def VST1d64QPseudoWB_register : VSTQQWBPseudo; // VST2 : Vector Store (multiple 2-element structures) -class VST2D op11_8, bits<4> op7_4, string Dt> - : NLdSt<0, 0b00, op11_8, op7_4, (outs), - (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2), - IIC_VST2, "vst2", Dt, "\\{$Vd, $src2\\}, $Rn", "", []> { +class VST2D op11_8, bits<4> op7_4, string Dt, RegisterOperand VdTy> + : NLdSt<0, 0b00, op11_8, op7_4, (outs), (ins addrmode6:$Rn, VdTy:$Vd), + IIC_VST2, "vst2", Dt, "$Vd, $Rn", "", []> { let Rm = 0b1111; let Inst{5-4} = Rn{5-4}; let DecoderMethod = "DecodeVSTInstruction"; } -class VST2Q op7_4, string Dt> - : NLdSt<0, 0b00, 0b0011, op7_4, (outs), - (ins addrmode6:$Rn, DPR:$Vd, DPR:$src2, DPR:$src3, DPR:$src4), - IIC_VST2x2, "vst2", Dt, "\\{$Vd, $src2, $src3, $src4\\}, $Rn", - "", []> { +class VST2Q op7_4, string Dt, RegisterOperand VdTy> + : NLdSt<0, 0b00, 0b0011, op7_4, (outs), (ins addrmode6:$Rn, VdTy:$Vd), + IIC_VST2x2, "vst2", Dt, "$Vd, $Rn", "", []> { let Rm = 0b1111; let Inst{5-4} = Rn{5-4}; let DecoderMethod = "DecodeVSTInstruction"; } -def VST2d8 : VST2D<0b1000, {0,0,?,?}, "8">; -def VST2d16 : VST2D<0b1000, {0,1,?,?}, "16">; -def VST2d32 : VST2D<0b1000, {1,0,?,?}, "32">; +def VST2d8 : VST2D<0b1000, {0,0,?,?}, "8", VecListTwoD>; +def VST2d16 : VST2D<0b1000, {0,1,?,?}, "16", VecListTwoD>; +def VST2d32 : VST2D<0b1000, {1,0,?,?}, "32", VecListTwoD>; -def VST2q8 : VST2Q<{0,0,?,?}, "8">; -def VST2q16 : VST2Q<{0,1,?,?}, "16">; -def VST2q32 : VST2Q<{1,0,?,?}, "32">; +def VST2q8 : VST2Q<{0,0,?,?}, "8", VecListFourD>; +def VST2q16 : VST2Q<{0,1,?,?}, "16", VecListFourD>; +def VST2q32 : VST2Q<{1,0,?,?}, "32", VecListFourD>; def VST2d8Pseudo : VSTQPseudo; def VST2d16Pseudo : VSTQPseudo; @@ -1532,27 +1529,24 @@ def VST2q16Pseudo : VSTQQPseudo; def VST2q32Pseudo : VSTQQPseudo; // ...with address register writeback: -class VST2DWB op11_8, bits<4> op7_4, string Dt> +class VST2DWB op11_8, bits<4> op7_4, string Dt, RegisterOperand VdTy> : NLdSt<0, 0b00, op11_8, op7_4, (outs GPR:$wb), - (ins addrmode6:$Rn, am6offset:$Rm, DPR:$Vd, DPR:$src2), - IIC_VST2u, "vst2", Dt, "\\{$Vd, $src2\\}, $Rn$Rm", - "$Rn.addr = $wb", []> { + (ins addrmode6:$Rn, am6offset:$Rm, VdTy:$Vd), + IIC_VST2u, "vst2", Dt, "$Vd, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{5-4} = Rn{5-4}; let DecoderMethod = "DecodeVSTInstruction"; } class VST2QWB op7_4, string Dt> : NLdSt<0, 0b00, 0b0011, op7_4, (outs GPR:$wb), - (ins addrmode6:$Rn, am6offset:$Rm, - DPR:$Vd, DPR:$src2, DPR:$src3, DPR:$src4), IIC_VST2x2u, - "vst2", Dt, "\\{$Vd, $src2, $src3, $src4\\}, $Rn$Rm", - "$Rn.addr = $wb", []> { + (ins addrmode6:$Rn, am6offset:$Rm, VecListFourD:$Vd), IIC_VST2x2u, + "vst2", Dt, "$Vd, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{5-4} = Rn{5-4}; let DecoderMethod = "DecodeVSTInstruction"; } -def VST2d8_UPD : VST2DWB<0b1000, {0,0,?,?}, "8">; -def VST2d16_UPD : VST2DWB<0b1000, {0,1,?,?}, "16">; -def VST2d32_UPD : VST2DWB<0b1000, {1,0,?,?}, "32">; +def VST2d8_UPD : VST2DWB<0b1000, {0,0,?,?}, "8", VecListTwoD>; +def VST2d16_UPD : VST2DWB<0b1000, {0,1,?,?}, "16", VecListTwoD>; +def VST2d32_UPD : VST2DWB<0b1000, {1,0,?,?}, "32", VecListTwoD>; def VST2q8_UPD : VST2QWB<{0,0,?,?}, "8">; def VST2q16_UPD : VST2QWB<{0,1,?,?}, "16">; @@ -1567,12 +1561,12 @@ def VST2q16Pseudo_UPD : VSTQQWBPseudo; def VST2q32Pseudo_UPD : VSTQQWBPseudo; // ...with double-spaced registers -def VST2b8 : VST2D<0b1001, {0,0,?,?}, "8">; -def VST2b16 : VST2D<0b1001, {0,1,?,?}, "16">; -def VST2b32 : VST2D<0b1001, {1,0,?,?}, "32">; -def VST2b8_UPD : VST2DWB<0b1001, {0,0,?,?}, "8">; -def VST2b16_UPD : VST2DWB<0b1001, {0,1,?,?}, "16">; -def VST2b32_UPD : VST2DWB<0b1001, {1,0,?,?}, "32">; +def VST2b8 : VST2D<0b1001, {0,0,?,?}, "8", VecListTwoQ>; +def VST2b16 : VST2D<0b1001, {0,1,?,?}, "16", VecListTwoQ>; +def VST2b32 : VST2D<0b1001, {1,0,?,?}, "32", VecListTwoQ>; +def VST2b8_UPD : VST2DWB<0b1001, {0,0,?,?}, "8", VecListTwoQ>; +def VST2b16_UPD : VST2DWB<0b1001, {0,1,?,?}, "16", VecListTwoQ>; +def VST2b32_UPD : VST2DWB<0b1001, {1,0,?,?}, "32", VecListTwoQ>; // VST3 : Vector Store (multiple 3-element structures) class VST3D op11_8, bits<4> op7_4, string Dt> diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index ae18decc53e..dee04ead532 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -2281,18 +2281,6 @@ static DecodeStatus DecodeVSTInstruction(llvm::MCInst &Inst, unsigned Insn, // Second input register switch (Inst.getOpcode()) { - case ARM::VST2d8: - case ARM::VST2d16: - case ARM::VST2d32: - case ARM::VST2d8_UPD: - case ARM::VST2d16_UPD: - case ARM::VST2d32_UPD: - case ARM::VST2q8: - case ARM::VST2q16: - case ARM::VST2q32: - case ARM::VST2q8_UPD: - case ARM::VST2q16_UPD: - case ARM::VST2q32_UPD: case ARM::VST3d8: case ARM::VST3d16: case ARM::VST3d32: @@ -2308,12 +2296,6 @@ static DecodeStatus DecodeVSTInstruction(llvm::MCInst &Inst, unsigned Insn, if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder))) return MCDisassembler::Fail; break; - case ARM::VST2b8: - case ARM::VST2b16: - case ARM::VST2b32: - case ARM::VST2b8_UPD: - case ARM::VST2b16_UPD: - case ARM::VST2b32_UPD: case ARM::VST3q8: case ARM::VST3q16: case ARM::VST3q32: @@ -2335,12 +2317,6 @@ static DecodeStatus DecodeVSTInstruction(llvm::MCInst &Inst, unsigned Insn, // Third input register switch (Inst.getOpcode()) { - case ARM::VST2q8: - case ARM::VST2q16: - case ARM::VST2q32: - case ARM::VST2q8_UPD: - case ARM::VST2q16_UPD: - case ARM::VST2q32_UPD: case ARM::VST3d8: case ARM::VST3d16: case ARM::VST3d32: @@ -2377,12 +2353,6 @@ static DecodeStatus DecodeVSTInstruction(llvm::MCInst &Inst, unsigned Insn, // Fourth input register switch (Inst.getOpcode()) { - case ARM::VST2q8: - case ARM::VST2q16: - case ARM::VST2q32: - case ARM::VST2q8_UPD: - case ARM::VST2q16_UPD: - case ARM::VST2q32_UPD: case ARM::VST4d8: case ARM::VST4d16: case ARM::VST4d32: diff --git a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp index 827883dd49c..662097aee4a 100644 --- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp +++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp @@ -1045,3 +1045,13 @@ void ARMInstPrinter::printVectorListTwoAllLanes(const MCInst *MI, O << "{" << getRegisterName(MI->getOperand(OpNum).getReg()) << "[], " << getRegisterName(MI->getOperand(OpNum).getReg() + 1) << "[]}"; } + +void ARMInstPrinter::printVectorListTwoSpaced(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) << "}"; +} + diff --git a/lib/Target/ARM/InstPrinter/ARMInstPrinter.h b/lib/Target/ARM/InstPrinter/ARMInstPrinter.h index b1fe9a142fe..05db2d25424 100644 --- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.h +++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.h @@ -137,6 +137,8 @@ public: raw_ostream &O); void printVectorListTwoAllLanes(const MCInst *MI, unsigned OpNum, raw_ostream &O); + void printVectorListTwoSpaced(const MCInst *MI, unsigned OpNum, + raw_ostream &O); }; } // end namespace llvm diff --git a/test/MC/ARM/neon-vst-encoding.s b/test/MC/ARM/neon-vst-encoding.s index e23845649f7..69bdd242fe1 100644 --- a/test/MC/ARM/neon-vst-encoding.s +++ b/test/MC/ARM/neon-vst-encoding.s @@ -31,19 +31,19 @@ @ CHECK: vst1.64 {d16, d17, d18, d19}, [r3], r2 @ encoding: [0xc2,0x02,0x43,0xf4] -@ vst2.8 {d16, d17}, [r0, :64] -@ vst2.16 {d16, d17}, [r0, :128] -@ vst2.32 {d16, d17}, [r0] -@ vst2.8 {d16, d17, d18, d19}, [r0, :64] -@ vst2.16 {d16, d17, d18, d19}, [r0, :128] -@ vst2.32 {d16, d17, d18, d19}, [r0, :256] - -@ FIXME: vst2.8 {d16, d17}, [r0, :64] @ encoding: [0x1f,0x08,0x40,0xf4] -@ FIXME: vst2.16 {d16, d17}, [r0, :128] @ encoding: [0x6f,0x08,0x40,0xf4] -@ FIXME: vst2.32 {d16, d17}, [r0] @ encoding: [0x8f,0x08,0x40,0xf4] -@ FIXME: vst2.8 {d16, d17, d18, d19}, [r0, :64] @ encoding: [0x1f,0x03,0x40,0xf4] -@ FIXME: vst2.16 {d16, d17, d18, d19}, [r0, :128] @ encoding: [0x6f,0x03,0x40,0xf4] -@ FIXME: vst2.32 {d16, d17, d18, d19}, [r0, :256] @ encoding: [0xbf,0x03,0x40,0xf4] + vst2.8 {d16, d17}, [r0, :64] + vst2.16 {d16, d17}, [r0, :128] + vst2.32 {d16, d17}, [r0] + vst2.8 {d16, d17, d18, d19}, [r0, :64] + vst2.16 {d16, d17, d18, d19}, [r0, :128] + vst2.32 {d16, d17, d18, d19}, [r0, :256] + +@ CHECK: vst2.8 {d16, d17}, [r0, :64] @ encoding: [0x1f,0x08,0x40,0xf4] +@ CHECK: vst2.16 {d16, d17}, [r0, :128] @ encoding: [0x6f,0x08,0x40,0xf4] +@ CHECK: vst2.32 {d16, d17}, [r0] @ encoding: [0x8f,0x08,0x40,0xf4] +@ CHECK: vst2.8 {d16, d17, d18, d19}, [r0, :64] @ encoding: [0x1f,0x03,0x40,0xf4] +@ CHECK: vst2.16 {d16, d17, d18, d19}, [r0, :128] @ encoding: [0x6f,0x03,0x40,0xf4] +@ CHECK: vst2.32 {d16, d17, d18, d19}, [r0, :256] @ encoding: [0xbf,0x03,0x40,0xf4] @ vst3.8 {d16, d17, d18}, [r0, :64] diff --git a/test/MC/Disassembler/ARM/neont2.txt b/test/MC/Disassembler/ARM/neont2.txt index 6f01f522ad9..ff1838e466e 100644 --- a/test/MC/Disassembler/ARM/neont2.txt +++ b/test/MC/Disassembler/ARM/neont2.txt @@ -1586,5 +1586,5 @@ # CHECK: vst4.32 {d17[0], d19[0], d21[0], d23[0]}, [r0] 0x63 0xf9 0x37 0xc9 -# CHECK: vld2.8 {d28, d29}, [r3, :256], r7 +# CHECK: vld2.8 {d28, d30}, [r3, :256], r7 -- 2.34.1