From: Hao Liu Date: Mon, 25 Nov 2013 01:53:26 +0000 (+0000) Subject: Fixed a bug about disassembling AArch64 post-index load/store single element instruct... X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=e04ed6b8b1b03933cfc73c8c0b5c3d5df2b618fd;p=oota-llvm.git Fixed a bug about disassembling AArch64 post-index load/store single element instructions. ie. echo "0x00 0x04 0x80 0x0d" | ../bin/llvm-mc -triple=aarch64 -mattr=+neon -disassemble echo "0x00 0x00 0x80 0x0d" | ../bin/llvm-mc -triple=aarch64 -mattr=+neon -disassemble will be disassembled into the same instruction st1 {v0b}[0], [x0], x0. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195591 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp index f003d8c04b2..65f477642d7 100644 --- a/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -1117,7 +1117,9 @@ static DecodeStatus DecodeVLDSTLanePostInstruction(MCInst &Inst, unsigned Insn, bool Is64bitVec = false; bool IsLoadDup = false; bool IsLoad = false; - unsigned TransferBytes = 0; // The total number of bytes transferred. + // The total number of bytes transferred. + // TransferBytes = NumVecs * OneLaneBytes + unsigned TransferBytes = 0; unsigned NumVecs = 0; unsigned Opc = Inst.getOpcode(); switch (Opc) { @@ -1511,17 +1513,20 @@ static DecodeStatus DecodeVLDSTLanePostInstruction(MCInst &Inst, unsigned Insn, unsigned Q = fieldFromInstruction(Insn, 30, 1); unsigned S = fieldFromInstruction(Insn, 10, 3); unsigned lane = 0; - switch (NumVecs) { - case 1: - lane = (Q << 3) & S; + // Calculate the number of lanes by number of vectors and transfered bytes. + // NumLanes = 16 bytes / bytes of each lane + unsigned NumLanes = 16 / (TransferBytes / NumVecs); + switch (NumLanes) { + case 16: // A vector has 16 lanes, each lane is 1 bytes. + lane = (Q << 3) | S; break; - case 2: - lane = (Q << 2) & (S >> 1); - break; - case 3: - lane = (Q << 1) & (S >> 2); + case 8: + lane = (Q << 2) | (S >> 1); break; case 4: + lane = (Q << 1) | (S >> 2); + break; + case 2: lane = Q; break; } diff --git a/test/MC/Disassembler/AArch64/neon-instructions.txt b/test/MC/Disassembler/AArch64/neon-instructions.txt index 9f9e7772857..03974806cd9 100644 --- a/test/MC/Disassembler/AArch64/neon-instructions.txt +++ b/test/MC/Disassembler/AArch64/neon-instructions.txt @@ -2126,14 +2126,14 @@ # Post-index of vector load/store single N-element structure to/from # one lane of N consecutive registers (N = 1,2,3,4) #---------------------------------------------------------------------- -# CHECK: ld1 {v0.b}[0], [x0], #1 -# CHECK: ld2 {v15.h, v16.h}[0], [x15], #4 -# CHECK: ld3 {v31.s, v0.s, v1.s}[0], [sp], x3 +# CHECK: ld1 {v0.b}[9], [x0], #1 +# CHECK: ld2 {v15.h, v16.h}[7], [x15], #4 +# CHECK: ld3 {v31.s, v0.s, v1.s}[3], [sp], x3 # CHECK: ld4 {v0.d, v1.d, v2.d, v3.d}[1], [x0], #24 -# CHECK: st1 {v0.d}[0], [x0], #8 -# CHECK: st2 {v31.s, v0.s}[0], [sp], #8 -# CHECK: st3 {v15.h, v16.h, v17.h}[0], [x15], #6 -# CHECK: st4 {v0.b, v1.b, v2.b, v3.b}[1], [x0], x5 +# CHECK: st1 {v0.d}[1], [x0], #8 +# CHECK: st2 {v31.s, v0.s}[3], [sp], #8 +# CHECK: st3 {v15.h, v16.h, v17.h}[7], [x15], #6 +# CHECK: st4 {v0.b, v1.b, v2.b, v3.b}[9], [x0], x5 0x00,0x04,0xdf,0x4d 0xef,0x59,0xff,0x4d 0xff,0xb3,0xc3,0x4d